Reflect
ES6新增,有“反射、拦截”之意。提供拦截JS操作的方法(与proxy一致,后有),一般与Proxy共用。
基本语法
Reflect.set(target, propertyKey, value)
特点
- 语法变体,并无太大创新之处;
- Reflect与Object方法相比 在异常处理方面较为温和;
- get()与set()中receiver参数有大用。receiver参数可以把调用对象当作target参数,而不是原始Proxy构造的对象。
let me = { _name: '周树人', get name() { return this._name; } } let meProxy = new Proxy(me, { get(target, prop, receiver) { return target[prop]; //或 return Reflect.get(target, prop, receiver) } }) let person = { __proto__: meProxy, _name: '鲁迅' }; person.name // 此时为周树人,若用Reflect,则为 鲁迅
为何Reflect和Proxy代理一起使用
- Reflect提供的所有静态方法和Proxy第2个handle参数方法是一模一样的。
- Proxy get/set()方法需要的返回值正是Reflect的get/set方法的返回值,可以天然配合使用,比直接对象赋值/获取值要更方便和准确。
- receiver参数具有不可替代性。
Proxy
ES6新增,Proxy有“代理”之意。用于以简洁易懂的形式拦截与自定义对象的某些操作(如属性查找、赋值、枚举、函数调用等)。是代理模式在Js上的体现。
基本语法
let p = new Proxy(target, handler);
参数:
- target 是需要被proxy包装的对象(任何类型的对象,数组,函数等等);
- handler 也是一个对象,声明了一些需要代理的操作.
handler:
- get(target, prop, receiver) 拦截 读取属性操作;
- set(target, prop, value, receiver) 捕获 设置属性值操作 ;
- has(target, prop) 捕获 in 操作符;
- construct(target, args) 捕获 new 操作符;
- apply(target, obj, args) 捕获 函数调用 ;
- deleteProperty(target, prop) 捕获 delete 操作符;
- defineProperty(target, prop, desc) 捕获 defineProperty 方法;
- getPrototypeOf(target) 捕获 getPrototypeOf 方法;
- setPrototypeOf(target, prototype) 捕获 setPrototypeOf 方法;
- getOwnPropertyDescriptor(target, prop) 捕获;getOwnPropertyDescriptor 方法;
- ownKeys(target) 捕获 getOwnPropertyNames 和 getOwnPropertySymbols 方法;
- isEXtensible(target) 捕获 isEXtensible 方法;
- preventExtensions(target) 捕获 preventExtensions 方法。
target -- 被代理对象, prop -- 属性名, receiver -- 最初被调用的对象
实例
let p = new Proxy({}, {
get(target, prop) {
...
},
set(obj, prop, value) {
...
},
deleteProperty(target, prop) {
...
}
})
p.name = "name";
p.name;
delete p.name;
Vue3 弃defineProperty ,用Proxy
都知Vue3中响应原理发生了变化,放弃defineProperty ,改用Proxy。
原因如下:
- defineProperty无法检测对象的动态添加和删除属性;
- 无法检测到数组的下标和length属性的变更(原本可以检测,vue在实现上放弃了,参考)
- ...
这导致让我们不得不使用一些不自然的方法去解决这些问题,$set, $delete等,而Proxy可以解决这些问题,同时还可以更强大。
总的说: defineProperty代理了对象已有的属性,而Proxy 代理了整个对象。
结语
以上出于个人对资料整理,喜欢掘金的md主题。