1、對象賦值的兩種方式bash
一是「=」賦值,一是Object.defineProperty方法,而當下流行框架中普遍應用的雙向綁定和數據監聽等,就是利用的第二種方式,關於此方法很少講,可參考框架
developer.mozilla.org/zh-CN/docs/…
dom
須要注意一點的是,函數
var bValue;
Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});
o.b = 38;複製代碼
雖然其中set方法是這樣寫的,ui
set : function(newValue){
bValue = newValue;
},複製代碼
因此此處的a.b=arg不一樣於通常的. 語法,而是已經觸發了setter了spa
2、爲何Object.defineProperty能實現雙向綁定和數據監聽呢.net
由於Object.defineProperty方法裏有getter和setter函數對,你能夠把它理解爲一個能夠觸發的函數,觸發事件就是setter對應的屬性被改變雙向綁定
eg:code
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被從新定義
複製代碼
3、框架裏的具體作法是怎樣的呢?對象
一句話描述,就是把在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);
複製代碼
固然,真正要解決的問題遠比上述複雜,好比更深層次的屬性要利用到遞歸方法等等。
參考資料: