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
参考链接:https://segmentfault.com/a/1190000015483195
首先罗列Object.defineProperty()的缺点: 1、Object.defineProperty()不会监测到数组引用不变的操作(比如push/pop等); 2、Object.defineProperty()只能监测到对象的属性的改变, 即如果有深度嵌套的对象则需要再次给之绑定Object.defineProperty();
Object.defineProperty()
push/pop
关于Proxy的优点 1、可以劫持数组的改变; 2、defineProperty是对属性的劫持,Proxy是对对象的劫持;
Proxy
defineProperty
为了加深理解,我们来举几个例子: 先来看看为什么说Object.defineProperty()不能监测到数组变化:
const data = { list: [] } Object.keys(data).forEach(function (key) { let value = data[key] Object.defineProperty(data, key, { enumerable: true, configurable: true, get () { return value }, set (newValue) { console.log('set value') value = newValue return true } }) }) // 所谓对数组的监控,即能检测到数组元素的增加和删除 data.list.push(1) // nothing happen console.log(data.list) data.list = [2, 3] // set value console.log(data.list)
当监控数组数据对象的时候,实质上就是监控数组的地址,地址不变也就不会被监测到,所以我们向 list 里 push 元素的时候并没有触发打印;当我们直接替换 list 对象的时候就触发了打印。所以这就是Object.defineProperty在数组监控方面的不足。 我们总是说 Vue 使用 hack 方法弥补了这个缺陷,那么看下其大致思路:
Object.defineProperty
let arrayMethod = Object.create(Array.prototype); ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) { Object.defineProperty(arrayMethod, method, { enumerable: true, configurable: true, value: function () { let args = [...arguments] Array.prototype[method].apply(this, args); console.log(`operation: ${method}`) dep.notify(); } }) }); [Array Object].__proto__ = arrayMethod;
其核心思想就是覆写数组对象中的方法,在调用数组方法的同时能触发回调。同时这样做的好处是,仅仅是数据中的数组对象的原型被修改掉了,并不会影响到全局的数组对象。 最后用 proxy 来试下其是否能检测到数组元素变化:
覆写
const data = { list: [1, 2, 3, 4] } const proxyArr = new Proxy (data.list, { get: function (target, key, receiver) { return Reflect.get(target, key, receiver) }, set: function (target, key, value, receiver) { console.log(target, key, value, receiver) return Reflect.set(target, key, value, receiver) } }) proxyArr.push(2) // [ 1, 2, 3, 4 ] '4' 2 [ 1, 2, 3, 4 ] // [ 1, 2, 3, 4, 2 ] 'length' 5 [ 1, 2, 3, 4, 2 ] proxyArr.shift() /* [ 1, 2, 3, 4 ] '4' 2 [ 1, 2, 3, 4 ] [ 1, 2, 3, 4, 2 ] 'length' 5 [ 1, 2, 3, 4, 2 ] [ 1, 2, 3, 4, 2 ] '0' 2 [ 1, 2, 3, 4, 2 ] [ 2, 2, 3, 4, 2 ] '1' 3 [ 2, 2, 3, 4, 2 ] [ 2, 3, 3, 4, 2 ] '2' 4 [ 2, 3, 3, 4, 2 ] [ 2, 3, 4, 4, 2 ] '3' 2 [ 2, 3, 4, 4, 2 ] [ 2, 3, 4, 2, <1 empty item> ] 'length' 4 [ 2, 3, 4, 2, <1 empty item> ] */
可以看到确实可以监测到数组元素变化。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
参考链接:https://segmentfault.com/a/1190000015483195
首先罗列
Object.defineProperty()
的缺点:1、
Object.defineProperty()
不会监测到数组引用不变的操作(比如push/pop
等);2、
Object.defineProperty()
只能监测到对象的属性的改变, 即如果有深度嵌套的对象则需要再次给之绑定Object.defineProperty()
;关于
Proxy
的优点1、可以劫持数组的改变;
2、
defineProperty
是对属性的劫持,Proxy
是对对象的劫持;为了加深理解,我们来举几个例子:
先来看看为什么说
Object.defineProperty()
不能监测到数组变化:当监控数组数据对象的时候,实质上就是监控数组的地址,地址不变也就不会被监测到,所以我们向 list 里 push 元素的时候并没有触发打印;当我们直接替换 list 对象的时候就触发了打印。所以这就是
Object.defineProperty
在数组监控方面的不足。我们总是说 Vue 使用 hack 方法弥补了这个缺陷,那么看下其大致思路:
其核心思想就是
覆写
数组对象中的方法,在调用数组方法的同时能触发回调。同时这样做的好处是,仅仅是数据中的数组对象的原型被修改掉了,并不会影响到全局的数组对象。最后用 proxy 来试下其是否能检测到数组元素变化:
可以看到确实可以监测到数组元素变化。
The text was updated successfully, but these errors were encountered: