vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定的原理:結(jié)合發(fā)布-訂閱模式较幌,通過(guò)ES5新增的Object.defineProperty()方法劫持各個(gè)屬性的setter和getter,Observer監(jiān)聽(tīng)數(shù)據(jù)的變動(dòng)
Object.defineProperty(要修改的對(duì)象, 對(duì)象要修改的屬性名稱(chēng), 屬性描述符)
屬性描述符:數(shù)據(jù)描述符和存取描述符(存取描述符是由 getter 函數(shù)和 setter 函數(shù)所描述的屬性)
數(shù)據(jù)描述符和存取描述符共享鍵值:
- configurable:屬性是否能刪改(是否可配)熟丸,默認(rèn)為false
- enumerable:屬性是否出現(xiàn)在對(duì)象的枚舉屬性震桶,默認(rèn)為false
- writable:屬性是否能被賦值運(yùn)算符改變磕仅, 默認(rèn)為false
數(shù)據(jù)描述符鍵值:
- value:屬性對(duì)應(yīng)的值,默認(rèn)為undefined
- writable
存取描述符鍵值:
- set:屬性的setter函數(shù),默認(rèn)為undefined
- get:屬性的getter函數(shù),默認(rèn)為undefined
var o = {}; // 創(chuàng)建一個(gè)新對(duì)象
// 在對(duì)象中添加一個(gè)設(shè)置了數(shù)據(jù)描述符屬性的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
// 給對(duì)象o添加一個(gè)a屬性商佑,值為37
// 在對(duì)象中添加一個(gè)設(shè)置了存取描述符屬性的示例
var bValue = 38;
Object.defineProperty(o, "b", {
get() { return bValue; },
set(newValue) { bValue = newValue; },
enumerable : true,
configurable : true
});
o.b; // 38
// 給對(duì)象o添加一個(gè)b屬性,值為 38
// 數(shù)據(jù)描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {
value: 0x9f91102,
get() { return 0xdeadbeef; }
});
Object.defineProperties(要修改的對(duì)象, {對(duì)象屬性名:{屬性描述符},})
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
});