Skip to content

Object.defineProperty与Proxy #5

Description

@twosugar

vue2.0的双向绑定就是基Object.defineProperty,而vue3.0已将Object.defineProperty替换成了Proxy,vue做了这层改变和他们两的特性息息相关。

Object.defineProperty问题

  • Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应(可以用一个新数组替代解决);
  • Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy可以劫持整个对象,并返回一个新的对象。

Proxy特点

  • 可以劫持整个对象,并返回一个新对象
  • 有13种劫持操作
  • Proxy是es6提供的,兼容性不好,无法用polyfill磨平

用Object.defineProperty手写一个数据双向绑定案例

<body>
  hello,world
  <input type="text" id="model">
  <p id="word"></p>
</body>
<script>
  const model = document.getElementById("model")
  const word = document.getElementById("word")
  var obj= {};
  Object.defineProperty(obj, "model", {
    get: function() {
       return model.value
    },
    set: function(newValue) {
      model.value = newValue
      word.innerHTML = newValue
    }
  })
  document.addEventListener("keyup",function(e){
    obj.model = e.target.value
  })
</script>

Proxy例子

<body>
  hello,world
  <input type="text" id="model">
  <p id="word"></p>
</body>
<script>
  const model = document.getElementById("model")
  const word = document.getElementById("word")
  var obj= {};

  const newObj = new Proxy(obj, {
      get: function(target, key, receiver) {
        console.log(`getting ${key}!`);
        return Reflect.get(target, key, receiver);
      },
      set: function(target, key, value, receiver) {
        console.log('setting',target, key, value, receiver);
        if (key === "text") {
          model.value = value;
          word.innerHTML = value;
        }
        return Reflect.set(target, key, value, receiver);
      }
    });

  model.addEventListener("keyup",function(e){
    newObj.text = e.target.value
  })
</script>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions