Object.defineProperty與雙向繫結、資料監聽

前端開膛手發表於2018-11-08

一、物件賦值的兩種方式

一是“=”賦值,一是Object.defineProperty方法,而當下流行框架中廣泛應用的雙向繫結和資料監聽等,就是利用的第二種方式,關於此方法不多講,可參考

developer.mozilla.org/zh-CN/docs/…

需要注意一點的是,

var bValue;
Object.defineProperty(o, "b", {
  get : function(){
    return bValue;
  },
  set : function(newValue){
    bValue = newValue;
  },
  enumerable : true,
  configurable : true
});

o.b = 38;複製程式碼

雖然其中set方法是這樣寫的,

set : function(newValue){
    bValue = newValue;
  },複製程式碼

所以此處的a.b=arg不同於一般的. 語法,而是已經觸發了setter了

二、為什麼Object.defineProperty能實現雙向繫結和資料監聽呢

因為Object.defineProperty方法裡有getter和setter函式對,你可以把它理解為一個可以觸發的函式,觸發事件就是setter對應的屬性被改變

eg:

var bValue = 38;
Object.defineProperty(o, 'b', {
  get: function() { return bValue; },
  set: function(newValue) { 
    bValue = newValue; 
    you can do something, like update the new data to virual dom! 
  },
  enumerable: true,
  configurable: true
});
o.b; // 38
//屬性”b”被設定到物件o上,並且值為38。
//現在o.b的值指向bValue變數,除非o.b被重新定義
複製程式碼

三、框架裡的具體做法是怎樣的呢?

一句話描述,就是把在data裡註冊的所有屬性都新增上對應的getter和setter函式對。

形象點,可以參照下面的方法:使用defineProperty方法封裝一個監聽屬性變動的函式。

var object = {
   name:'liwudi',
    age:34
}
function changeIt(object) {
    function descripterFun(value) {
        return {
            enumerable: true,
            get: function () {
                console.log('get it');
                return value;
            },
            set: function (newvalue) {
                console.log('set it');
                value = newvalue;
            }
        }
    }
    for(var i in object){
        Object.defineProperty(object, i, descripterFun(object[i]))
    }
}
changeIt(object);
console.log(object.name);
object.name = '我是中國人';
console.log(object);
複製程式碼

當然,真正要解決的問題遠比上述複雜,比如更深層次的屬性要利用到遞迴方法等等。

參考資料:

blog.csdn.net/yuhk231/art…

blog.csdn.net/mapbar_fron…


相關文章