Object.defineProperty 和 Proxy 实现响应式的区别

123 阅读1分钟

Object.defineProperty

Object.defineProperty 通过get和set实现响应式

const obj = {
    a:1,
    b:2
}
Object.defineProperty(obj,'a',{
    get(){
        console.log(`读取了对象 obj 的 属性 a`)
        return obj.a
    }
    set(val){
        // 判断新的值和原来的值是否一样,不一样就更改
        if(val !== obj.a){
            console.log(`更改了对象 obj 的 属性 a 的值`)
            // 这边可以处理一些其他逻辑,比如更新视图
            obj.a = val
        }
    }
})

缺点

  • 由于它是对象属性的监听,所以会对对象做深度遍历,会影响性能。
  • 遍历完成后,新增的属性无法实现响应式
  • 无法监听删除操作

Proxy

Proxy的监听是针对一个对象的,对整个对象的所有操作都会进入监听操作,这样就可以完全代理所有属性了,包括新增属性和删除属性,并且Proxy可以监听数组的变化。

function reactive(obj) {
    if (typeof obj !== 'object' && obj != null) {
        return obj
    }
    // 相当于在对象外层加拦截
    const observed = new Proxy(obj, {
        get(target, key, receiver) {
            const res = Reflect.get(target, key, receiver)
            console.log(`读取了对象 obj 的 属性 ${key}`)
            return res
        },
        set(target, key, value, receiver) {
            const res = Reflect.set(target, key, value, receiver)
            console.log(`更改了对象 obj 的 属性 ${key} 的值`)
            return res
        },
        deleteProperty(target, key) {
            const res = Reflect.deleteProperty(target, key)
            console.log(`删除了对象的属性 ${key}`)
            return res
        }
    })
    return observed
}