從Object.definedProperty中看vue的雙向數據的綁定


前言

Object.defineProperty是ES5中的方法,它可以直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。vue.js正式利用這種方法實現數據的雙向綁定,以達到響應式的目的。

1、語法

Object.defineProperty(object, propertyname, descriptor)  //參數(3個且必須)

2、參數詳解

  3.1、object:要在其上添加或修改屬性的對象。
  3.2、propertyname:一個包含屬性名稱的字符串。就是需要定義的屬性和方法。
  3.3、descriptor:可以包含以下屬性,默認情況下, writable, enumerable,configurable值為false

  value:屬性的值

  writable:如果為false,屬性的值就不能被重寫,只能為只讀了。

  enumerable:是否能枚舉,也就是否能在for...in循環中遍歷出來或在Object.keys中列舉出來。

  configurable:如果為false,就不能再設置他的(value,writable,configurable)。

 還有兩個方法 (雙向數據綁定正是利用了這兩個方法,即訪問器 )get() 和 set()

3、看看栗子

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

就是給a對象添加b屬性,並返回a對象;

再比如:把描述設置為不可寫; 

4、訪問器 set和get

set();一旦屬性被重新賦值,此方法被自動調用。
get();一旦屬性被訪問讀取,此方法被自動調用。
不能同時設置訪問器 (get 和 set) 和 wriable 或 value,否則會錯。

var a= {}
Object.defineProperty(a,"b",{
  set:function(val){
    console.log("賦值時候調用我,我的新值是"+ val)
    },
  get:function(){
    console.log("取值的時候調用我")
    return 123
   }
})
a.b =520          // 賦值時候調用我,我的新值是520
console.log(a.b)  // 取值的時候調用我, 返回我設置123,不是開始設置的520 

5、簡單雙向數據綁定

給對象a定義新的屬性b,並且定義屬性b的get和set方法,當a.b的時候會調用b屬性的get方法,給b屬性賦值的時候,會調用set方法,這就是修改數據的時候,視圖會自動更新的關鍵.(只能兼容IE8以上的瀏覽器,vue也是如此!)。

理解JavaScript中的雙向數據綁定

<label>輸入:</label><input type="text" id="demo1"><br/>
<label>輸出:</label> <input type="textarea" id="demo2"></input>

<script>
    var a={};
    var output=[];
    Object.defineProperty(a,'b',{   //給a對象添加b屬性
        set:function(val){
            output['b']=val;
        },
        get:function(){
            return output['b'];
        }
    })
    var demo1=document.querySelector('#demo1');
    var demo2=document.querySelector('#demo2');
    demo1.onkeyup=function(){
        a.b=demo1.value;//給a對象添加b屬性時候,觸發了a的set方法,此時#demo1的value值賦值給output['b']。
        demo2.value=output['b'];
    }

</script>

  

6、再看看Object.defineProperty實踐例子

直接在原型上添加一個不可遍歷的方法extend(),該方法可以把新對象賦值給舊對象;

Object.defineProperty(Object.prototype, 'extend',{
  value : function(def, opt) {
        for(var key in opt){
            def[key] = opt[key];
        }
    return def;
  },
  writable: true,
  enumerable : false
});

function func(options){
    let def = {
        payType: 'wechat',
        buyType: -1,
        isCard: false,
        toUid: -1,
        couponId: -1
    };
 
    let opt = extend(def, options);
 
    this.isCardPay = opt.isCard;
    this.payType = opt.payType;
    .......
}
 
//使用
fuc({
    payType: 'ali',
    buyType: 2,
    isCard: true,
    toUid: 123456,
    couponId: 667890
})

  

 7、vue怎么實現數據雙向綁定?

vue.js 則是采用數據劫持結合發布者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的settergetter,在數據變動時發布消息給訂閱者,觸發相應的監聽回調。

這里寫的很詳細。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM