这是模拟vue3响应数据的例子
const p = new Proxy([1, 2, 3], {
get(target, key, receiver) {
console.log('get: ', key)
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
console.log('set: ', key, value)
return Reflect.set(target, key, value, receiver)
}
})
p.push(100)
如题,我直接在target上修改也一样,为啥要多此一举使用Reflect呢?
const p = new Proxy([1, 2, 3], {
get(target, key, receiver) {
return target[key]
},
set(target, key, value, receiver) {
target[key] = value
return true
}
})
p.push(100)
console.log(p) //Proxy?{0: 1, 1: 2, 2: 3, 3: 100}
console.log(p[3]) //100
###不用 Reflect 也可以,
Reflect 这个 API 在 es6 中被提出,
目的是为了形成一个未来规范,
把操作对象相关的方法统一到 Reflect。
Proxy
也不是万能的,总会有缺点,js一些内建对象,例如 Map
,Set
,Date
等不能被Proxy
拦截,数组除外,对于简单数据处理,上面的代码完全可以
let map = new Map();
let proxy = new Proxy(map, {});
proxy.set('test', 1); //报错
另外Reflect.get/set
第三个参数比较关键,可以确定this
的指向
let myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
};
let myReceiverObject = {
foo: 4,
bar: 4,
};
Reflect.get(myObject, 'baz', myReceiverObject) 8
let Parent = new Proxy({
_name: 'parent',
get name() {
return this._name
}
},{
get: function(target, prop, receiver) {
return target[prop]
//return Reflect.get(target, prop, receiver)
}
})
let Child = {
_name: 'child'
}
Child.__proto__ = Parent
// Child继承Parent
console.log(Child._name)
// 输出却是parent 用Reflect.get()方式结果是Child
console.log(Child.name)
###其实还是对象的操作方式乱七八糟……
obj['a']=1在赋值
obj.a = 1也是赋值
delete obj.a是删除。
Reflect主要是为了提供统一格式的操作API吧。
因为Reflect里的操作方法名和proxy是一致的