Proxy 是拦截器,参考ES6Proxy Proxy 跟虚拟DOM有什么关系吗,数据层处理完数据,再生成虚拟DOM,由虚拟DOM去生成页面结构,再渲染Proxy 是位于数据层,操作的只是数据, 参考Vue.js入门(一)--MVVM框架理解 补充:Proxy这样设计的,你这问题等同于在问我1+1为什么等于2? 既然回答了你,我帮你找出为什么“1+1 = 2” PS:好好想想,为啥没人回答你?资料都给你了,去查就好了,不要只想坐享其成,这又不是什么思路或方向性问题需要人指点,希望之后多查查 前言 你的问题无非不就是Object.defineProperty不能监听数组长度变化,而Proxy可以监听? 一、Object.defineProperty MDN-Configurable中提到:当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。 首先对于数组,本身是因为不可监听length,造成了一系列push,pop等这种改变数组长度,无法监听到。 var arr = [1,2,3] Object.getOwnPropertyDescriptors(arr) /* => { 0: configurable: true enumerable: true value: 1 writable: true __proto__: Object 1: configurable: true enumerable: true value: 2 writable: true __proto__: Object 2: configurable: true enumerable: true value: 3 writable: true __proto__: Object length: configurable: false enumerable: false value: 3 writable: true __proto__: Object } */ 这里可以明确的看到length 属性的configurable是false,然后各大浏览器厂商包括JS本身,也不允许将length的configurable修改为true,修改后会抛出VM305:1 Uncaught TypeError: Cannot redefine property: length的错误,所以造成了pop,push这种会修改原数组长度的值都无法被监听到 而对于下面这种是可以的 var obj = {}, temp = 1 Objcet.defineProperty(obj,'list',{ set:function(value){ console.log("setted"); value = 1; }, get:function(){ return temp; } }); obj.list = []; // setted obj.list = [1,2,3]; // setted 因为这种是将一个新数组赋给obj.list, 而不是修改原数组 二、Proxy MDN-Proxy中提到:target 代理虚拟化的对象。它通常用作代理的存储后端。根据目标验证关于对象不可扩展性或不可配置属性的不变量(保持不变的语义)。 Array.length 就是不可配置的属性,故Proxy可以监听原数组中长度的变化。 三、Vue3 // vue3 使用 const arr = reactive([1,2,3]) 通过reactive函数, 将[1,2,3]包装成响应式对象,即Proxy对象,所以你可以通过push,pop等改变原数组长度的方法去实现监听 四、Note 不要问为啥Object.defineProperty为啥不允许监听数组长度,而非要引入Proxy对象,ECMAScript定的,谁知道呢? 多看书,多学习,你就会懂的更多。
Proxy 是位于数据层,操作的只是数据, 参考Vue.js入门(一)--MVVM框架理解
补充:
Proxy这样设计的,你这问题等同于在问我1+1为什么等于2?
既然回答了你,我帮你找出为什么“1+1 = 2”
前言
你的问题无非不就是Object.defineProperty不能监听数组长度变化,而Proxy可以监听?
一、Object.defineProperty
MDN-Configurable中提到:
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
首先对于数组,本身是因为不可监听length,造成了一系列push,pop等这种改变数组长度,无法监听到。
这里可以明确的看到length 属性的configurable是false,然后各大浏览器厂商包括JS本身,也不允许将length的configurable修改为true,修改后会抛出
VM305:1 Uncaught TypeError: Cannot redefine property: length
的错误,所以造成了pop,push这种会修改原数组长度的值都无法被监听到而对于下面这种是可以的
因为这种是将一个新数组赋给obj.list, 而不是修改原数组
二、Proxy
MDN-Proxy中提到:
target
代理虚拟化的对象。它通常用作代理的存储后端。根据目标验证关于
对象不可扩展性或不可配置
属性的不变量(保持不变的语义)。Array.length 就是不可配置的属性,故Proxy可以监听原数组中长度的变化。
三、Vue3
通过reactive函数, 将[1,2,3]包装成响应式对象,即Proxy对象,所以你可以通过push,pop等改变原数组长度的方法去实现监听
四、Note
不要问为啥Object.defineProperty为啥不允许监听数组长度,而非要引入Proxy对象,ECMAScript定的,谁知道呢?