We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在 vue2.x 版本中使用 Object.definedProperty 来劫持数据,实现数据双向绑定。我们来实现一个简单的数据劫持:
function observer(obj) { if (typeof obj === 'object') { for (const key in obj) { if (obj.hasOwnProperty(key)) { listener(obj, key); } } } } function listener(obj, key) { let curValue = obj[key]; observer(curValue); // 如果curValue是对象,进入递归 Object.defineProperty(obj, key, { get() { console.log('get-->', curValue); return curValue; }, set(newVal) { console.log('set-->', newVal); curValue = newVal; } }); }
上面写了个简单版的数据劫持,现在我们来测试一下:
const obj = { name: 'Jack', age: 20 }; observer(obj)
现在我们将 obj.name 改为 Tom: 灰常好,set 方法执行了,我们在更改数据前,劫持了数据。
obj.name
Tom
我们再看看获取 name: 灰常好,get 方法也执行了,我们在获取数据前,劫持了数据。
看上去很美好,但 Object.definedProperty 并不是完美的,它在有些情况下无法劫持数据:
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
const p = new Proxy(target, handler)
还记得 Object.defineProperty 的语法吗:
Object.defineProperty(obj, key, options);
从语法上就能发现一个最大的不同点:Object.defineProperty 监听的是对象的属性,而 Proxy 监听的是整个对象
所以我们不需要遍历对象,而是直接监听对象:
const obj = { arr: [] } const handler = { get(target, key, receiver){ console.log('get->', target[key]) if(typeof target[key] === 'object' && target[key] !== null) { return new Proxy(target[key], handler) } return target[key] }, set(target, key, value){ console.log('set->', key, value) return Reflect.set(target, key, value) } } const p = new Proxy(obj, handler)
上面我们监听的是一个空的对象,我们直接添加属性看看:
p.name = 'Jack';
这里注意,我们代理的是 obj,返回的是 p,所以要对 p 进行操作:
obj
p
真好,set 触发了。
我们再看看获取 name:
name
真好,get 也触发了。
我们再看看数组:
都可以非常好的监听到 get 、set,太强大了
关于 Proxy 的更多用法和说明,请看 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Object.definedProperty
在 vue2.x 版本中使用 Object.definedProperty 来劫持数据,实现数据双向绑定。我们来实现一个简单的数据劫持:
上面写了个简单版的数据劫持,现在我们来测试一下:
现在我们将
obj.name
改为Tom
:灰常好,set 方法执行了,我们在更改数据前,劫持了数据。
我们再看看获取 name:
灰常好,get 方法也执行了,我们在获取数据前,劫持了数据。
看上去很美好,但 Object.definedProperty 并不是完美的,它在有些情况下无法劫持数据:
Proxy
语法
还记得 Object.defineProperty 的语法吗:
从语法上就能发现一个最大的不同点:Object.defineProperty 监听的是对象的属性,而 Proxy 监听的是整个对象
所以我们不需要遍历对象,而是直接监听对象:
上面我们监听的是一个空的对象,我们直接添加属性看看:
这里注意,我们代理的是
obj
,返回的是p
,所以要对 p 进行操作:真好,set 触发了。
我们再看看获取
name
:真好,get 也触发了。
我们再看看数组:
都可以非常好的监听到 get 、set,太强大了
关于 Proxy 的更多用法和说明,请看 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
The text was updated successfully, but these errors were encountered: