Object.defineProperty与Proxy的使用

HaoOuBa
2021-02-22 / 2 评论 / 79 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年02月23日,已超过49天没有更新,若内容或图片失效,请留言反馈。

这个方法的主要用处是用来做数据劫持的,在vue2.x主要使用这个方法,在3.0中换成了proxy做数据劫持,数据劫持就是监听到数据的变化,然后可以做什么等

Object.defineProperty

/* 随便定义一个对象 */
let obj = {
    name: 'hello',
    age: 18,
    child: {
        sex: '女'
    }
}
observer(obj)
function observer(obj) {
    /* 判断传入进来的是否是对象 */
    if (obj.constructor === Object) {
        /* 循环对象 */
        for (let key in obj) {
            /* 如果值不是对象,则做劫持 */
            if (obj[key].constructor !== Object) {
                /* 定义一个临时变量,用于return出去 */
                let _value = obj[key]
                Object.defineProperty(obj, key, {
                    /* 设置属性可以被删除,可以被修改 */
                    configurable: true,
                    /* 设置属性可以被遍历 */
                    enumerable: true,
                    get() {
                        console.log('触发读取')
                        return _value
                    },
                    set(newVal) {
                        console.log('触发修改')
                        _value = newVal
                    }
                })
            } else {
                /* 否则进行递归,再次判断 */
                observer(obj[key])
            }
        }
    }
}

Proxy

let obj = {
    name: '小红',
    age: 1
}
obj = new Proxy(obj, {
    get(target, key) {
        console.log(target)
        console.log(key)
    },
    set(target, key, newVal) {
        console.log(target)
        console.log(key)
        console.log(newVal)
    }
})
console.log(obj)
3

评论 (2)

取消
  1. 头像
    PluginsKers
    Android · Google Chrome

    `Object.defineProperty`在新增属性的时候没办法追踪吗?表情

    回复
    1. 头像
      Joe 作者
      Windows 10 · Google Chrome
      @ PluginsKers

      这个我在vue里面测试了。vue里面也无法监听到新的属性值,但有个很巧妙的操作,如果读取了这个对象里的其他属性,再新增属性,就可以读取到。这是我写的demo

      ```html

      obj固有的属性name:{{ obj.name }}
      obj新增的属性asd:{{ obj.asd }} new Vue({ el: "#app", data: { obj: { name: "哈哈" } }, mounted() { setTimeout(() => { this.obj.name = '哦121212' this.obj.asd = '哦' console.log(this.obj); }, 3000) } })

      ```

      回复