神奇的Object.defineProperty

本文最后更新于:2023年12月5日 晚上

这个方法了不起啊, vue.js 和 avalon.js 都是通过他实现双向绑定.

几行代码简单了解一下

var a = {};
Object.defineProperty(a, "b", {
  value: 123,
});
consloe.log(a.b); //123

属性代理:有两个对象 data 和 obj , 要求不能直接操作 data, 而是通过操作 obj 间接的操作 data

var data = {age: 18}
var obj = {}
//1.给obj定义一个age属性
Object.defineProperty(obj,'age',{
    set: funtion(val){    //val是修改之后的属性值
        data.age = val
    }
    get: function(){
        return data.age
    }
})

//这样, 当设置obj的age属性值,data的age属性值也会随之改变, 当获取obj的age属性值, 实际获取的是data的age属性值, 就实现了属性代理

双向数据绑定:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>双向数据绑定</title>
  </head>
  <body>
    <input type="text" name="nickname" v-model="nickname" />
    <input type="text" name="age" v-model="age" />

    <script type="text/javascript">
      //构造函数 实现 DOM 和 data 的双向绑定
      function Obj(data) {
       # 不使用name, 只使用v-model属性也能锁定目标元素
       var models = document.querySelectorAll('input[v-model]')
       var that = this
       models.forEach(function(model){
        //DOM ==> data 的绑定
        //当input中的数据改变, data中的数据随之改变
        model.addEventListener('input',function(e){
         data[model.name] = e.target.value
        })

        // data ==> DOM 的绑定
        // 当data改变(注意这里data的改变是通过构造函数的实例ob来代理的), input中的值随之改变
        Object.defineProperty(that, model.name, {
         set: function(val) {
          data[model.name] = val
          model.value = val
         },
         get: function() {
          return data[model.name]
         }
        })
       })
      }
    </script>
    <script type="text/javascript">
      var data = {};
      var ob = new Obj(data);
    </script>
  </body>
</html>

神奇的Object.defineProperty
http://blog.lujinkai.cn/前端/Vue2/神奇的Object.defineProperty/
作者
像方便面一样的男子
发布于
2020年12月5日
更新于
2023年12月5日
许可协议