Reflect
是一个内置的对象,它提供拦截 JavaScript 操作的方法。 他可以与Proxy
结合使用以实现和Object.defineProperty
类似的功能,且性能更好。
// target 取值目标, key 键值, receiver getter/setter调用时的this值
Reflect.get(target, key, receiver)
Reflect.set(target, key, value, receiver)
new Proxy(proxyObj,{
get(target, key, receiver){
return target[key]
},
set(target, key, value, receiver){
target[key] = value
}
})
使用Reflect和Proxy实现响应式
// const data = {
// name: 'zhangsan',
// age: 18,
// address: {
// ctty: '广州花都',
// street: '旗岭街道',
// },
// };
const data = ['a', 'b', 'c'];
const proxyObj = new Proxy(data, {
get(target, key, receiver) {
// 只处理本身(非原型的数据)属性
const ownKeys = Reflect.ownKeys(target);
if (ownKeys.includes(key)) {
//监听
console.log('get', key);
}
const result = Reflect.get(target, key, receiver);
return result;
},
set(target, key, val, receiver) {
// 重复的数据不处理
if (val === target[key]) {
return true;
}
const result = Reflect.set(target, key, val, receiver);
return result;
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key);
return result;
},
});
proxyObj.push('d');
console.log(proxyObj);
Vue3之所以要使用Proxy
代替原先的Object.defineProperty
,原因在于:
1.无需再一层层递归observe
,性能更好,代码易读性加强
2.使用Reflect无需再区别对待Object
和Array
Reflect
其他用法:
Reflect.apply(fn, thisArgument, args) // 代替fn.apply()
Reflect.construct(Constructor,args) // 代替 new Constructor(...args)
Reflect.defineProperty(target, key, disc) // 代替Object.defineProperty(target,key,disc)
Reflect.getOwnPropertyDescriptor(target,key) // 代替Object.getOwnPropertyDescriptor(target,key)
Reflect.has(target,key) // 判断是否有key,相当于key in target, 注意:原型上的属性也会遍历到
Reflect.ownKeys(target) // 等价于[...Object.getOwnPropertyNames(target), ...Object.getOwnPropertySymbols(target)]
Reflect.setPrototypeOf(target, prototype)
Reflect.getPrototypeOf(target)