乐趣区

关于vue.js:defineProperty-和-Proxy区别直接上结论有一句废话你打我

在 Vue2 和 3 中 defineProperty 和 Proxy 都是用来实现响应式数据绑定的。实现的性能相似,然而两个 API 却有着实质的区别。

  1. 监听数据的角度

    1. defineproperty只能监听某个属性而不能监听整个对象。
    2. proxy不必设置具体属性,间接监听整个对象。
    3. defineproperty监听须要晓得是哪个对象的哪个属性,而 proxy 只须要晓得哪个对象就能够了。也就是会省去 for in 循环进步了效率。
  2. 监听对原对象的影响

    1. 因为 defineproperty 是通过在原对象身上新增或批改属性减少描述符的形式实现的监听成果,肯定会批改原数据。
    2. proxy 只是原对象的代理,proxy会返回一个代理对象不会在原对象上进行改变,对原数据无污染。
  3. 实现对数组的监听

    1. 因为数组 length 的特殊性 (length 的描述符 configurable 和 enumerable 为 false,并且妄图批改 configurable 为 True 的话 js 会间接报错:VM305:1 Uncaught TypeError: Cannot redefine property: length)
    2. defineproperty无奈监听数组长度变动, Vue只能通过重写数组办法的形式变现达成监听的成果,光重写数组办法还是不能解决批改数组下标时监听的问题,只能再应用自定义的 $set 的形式
    3. proxy 因为本身个性,是创立新的代理对象而不是在原数据身上监听属性,对代理对象进行操作时,所有的操作都会被捕获,包含数组的办法和 length 操作,再不须要重写数组办法和自定义 set 函数了。(代码示例在下方)

    4. 监听的范畴

    1. defineproperty只能监听到 valueget set 变动。
    2. proxy能够监听除 [[getOwnPropertyNames]] 以外所有 JS 的对象操作。(链接看下方)监听的范畴更大更全面。

点击查看 proxy 反对监听的对象操作方法(除 getOwnPropertyNames)

Proxy 监听数组变动示例:

let array = ['1', '2']
let arrayProxy = new Proxy(array, {get(target, key) {console.log('(key:', key + ") 产生了 get 操作")
        return target[key]
    },
    set(target, key, value) {console.log('(key:', key + ") 产生了 set 操作, value=" + value)
        return target[key] = value
    }
})
arrayProxy.push('我是 push 函数 push 到数组中的值')

// (key: push) 产生了 get 操作
// (key: length) 产生了 get 操作
// (key: 2) 产生了 set 操作, value= 我是 push 函数 push 到数组中的值
// (key: length) 产生了 set 操作, value= 3

// 从 log 能够看出 push length 等操作都被捕获了
退出移动版