Object.defineProperty() 和 ES2015 中新增的 Proxy 对象,会经常用来做数据劫持.
数据劫持:在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果.数据劫持最典型的应用———双向的数据绑定

  1. Vue 2.x 利用 Object.defineProperty(),并且把内部解耦为 Observer, Dep, 并使用 Watcher 相连
  2. Vue 在 3.x 版本之后改用 Proxy 进行实现

    Object.defineProperty()

    **Object.defineProperty()** 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

    语法

    QQ图片201839_03.png

    用法

    1. var a= {}
    2. Object.defineProperty(a,"b",{
    3. set:function(newValue){
    4. console.log("你要赋值给我 我的新值是"newValue)
    5. a['b'] = newValue;
    6. },
    7. get:function(){
    8. console.log("你取我的值")
    9. return a['b']
    10. }
    11. })
    12. a.b = 1 // 赋值,触发set方法
    13. console.log(a.b) // 调用值,触发get方法

    优点

  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平

    缺点

  • 不能监听数组的变化

  • 必须遍历对象的每个属性
  • 必须深层遍历嵌套的对象

    Proxy

    Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。

    语法

    QQ图片20201012204457.png

    用法

    1. let obj = {
    2. name: 'Eason',
    3. age: 30
    4. }
    5. let handler = {
    6. get (target, key, receiver) {
    7. console.log('get', key)
    8. return Reflect.get(target, key, receiver)
    9. },
    10. set (target, key, value, receiver) {
    11. console.log('set', key, value)
    12. return Reflect.set(target, key, value, receiver)
    13. }
    14. }
    15. let proxy = new Proxy(obj, handler)
    16. proxy.name = 'Zoe' // set name Zoe
    17. proxy.age = 18 // set age 18

    优点

  • Proxy 可以直接监听对象而非属性;

  • Proxy 可以直接监听数组的变化;
  • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
  • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

    缺点

  • Proxy 的兼容性不如 Object.defineProperty() (caniuse 的数据表明,QQ 浏览器和百度浏览器并不支持 Proxy,这对国内移动开发来说估计无法接受,但两者都支持 Object.defineProperty())

  • 不能使用 polyfill 来处理兼容性