Skip to content

Object.defineProperty 和 Proxy

Object.defineProperty

弊端: 1. 对对象的添加和删除操作,无法劫持到,vue2新增 $set $delete 2. 对数组的api无法劫持到 vue2重新数组api 3. 存在深层嵌套关系,无脑递归

js
let person = { name: 'zs', age: 18, code: {name: 'qd'} }
function dPropery(obj, key, value) {
    observer(value)
    Object.defineProperty(obj, key, {
        get: function() {
            console.log('get', key)
            return value
        },
        set: function(newValue) {
            if (newVlue == value) return
            observer(newValue)
            console.log('set', key)
            value = newValue
        }
    })
}

function observer(obj) {
    if (typeof obj != 'object' || obj == null) {
        return
    }
    for (let key in obj) {
        dProperty(obj, key, obj[key])
    }
}

Proxy

总结: 1. Proxy 直接可以劫持整个对象,并返回一个新对象,我们可以置操作新的对象达到响应式目的。 2. Proxy 可以直接监听数组变化。 3. Proxy 有多达13种拦截方法。 4. Proxy 通过懒加载,解决递归照成性能问题。 5. 不兼容IE

js
function reactive(obj) {
    // Proxy 有13种监听方法 相对应Reflect也有13种映射关系
    return new Proxy(obj, {
        get(target, key) {
            let res = Reflect.get(target, key)
            return isObj(res) ? reactive(res) : res
        },
        set(target, key, value) {
            return Reflect.set(target, key, value)
        },
        deleteProperty(target, key) {
            return Reflect.deleteProperty(target, key, value)
        }
    })
}
funciton isObj(obj) {
    if (typeof obj != 'obj' || obj == null) {
        return false
    }
    return true
}
let person = reactive({ name: 'zs', age: 18, code: {name: 'qd'} })

Released under the MIT License.