vue3实现数据响应时为啥要用到Reflect去修改目标对象?

张巨侠
  • 300

这是模拟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
回复
阅读 358
4 个回答

不用 Reflect 也可以,
Reflect 这个 API 在 es6 中被提出,
目的是为了形成一个未来规范,
把操作对象相关的方法统一到 Reflect。

Proxy也不是万能的,总会有缺点,js一些内建对象,例如 MapSetDate 等不能被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)

proxy缺点

其实还是对象的操作方式乱七八糟……
obj['a']=1在赋值
obj.a = 1也是赋值
delete obj.a是删除。
Reflect主要是为了提供统一格式的操作API吧。

因为Reflect里的操作方法名和proxy是一致的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
你知道吗?

宣传栏