vue.js的雙向數據綁定就是經過Object.defineProperty方法實現的,俗稱屬性攔截器javascript
Object.defineProperty()
方法會直接在一個對象上定義一個新屬性,或者修改一個已經存在的屬性, 並返回這個對象vue
1 // 語法: 2 /* 3 * @param: obj:須要定義屬性的對象; 4 * prop:須要定義或修改的屬性; 5 * descriptor:將被定義或修改屬性的描述符 6 */ 7 Object.defineProperty(obj,prop,descriptor)
對象裏目前存在的屬性描述符主要有兩種形式: 數據描述符和存取描述符.java
數據描述符: 擁有可寫或不可寫值的屬性* 函數
可選鍵值:
configurable: 當且僅當configurable爲true時,改屬性描述符纔可以被改變,也能被刪除
enumerable: 當其值爲true時,該屬性纔可以出如今對象的枚舉屬性中,默認爲false
writable: 當且僅當該屬性的值爲true時,該屬性才能被賦值運算符改變, 默認爲false。
value: 該屬性對應的值,能夠是任意有效的javascript的值(數值,對象,函數等),默認爲undefined
存取描述符: 由一對getter-setter函數功能來描述的屬性*spa
可選鍵值:
configurable: 當且僅當configurable爲true時,改屬性描述符纔可以被改變,也能被刪除
enumerable: 當其值爲true時,該屬性纔可以出如今對象的枚舉屬性中,默認爲false
get: 給屬性提供getter的方法,若是沒有 getter 則爲undefined。當咱們讀取某個屬性的時候,實際上是在對象內部調用了該 方法,此方法必需要有return語句。該方法返回值被用做屬性值。默認爲 undefined
set:設置屬性值的方法, 若是沒有 setter 則爲 undefined。該方法將接受惟一參數,並將該參數的新值分配給該屬性。默認爲 undefined。也就是說,當咱們設置某個屬性的時候,其實是在對象的內部調用了該方法
note:二者不能同時定義, 不然報錯==code
實例:對象
1 var a = {}; 2 Object.defineProperty(a, 'b', { 3 set: function(newValue) { 4 console.log('賦值操做, 賦值' + newValue); 5 }, 6 get: function() { 7 console.log('取值操做'); 8 return 2; 9 } 10 }); 11 a.b = 1; // 賦值操做,賦值1 12 a.b; // 取值操做2
Object對象有一個freeze的方法,用於實現對象屬性和方法的不可更改blog
1 // 使用方法: 2 const arr = [1,2,3,4]; 3 Object.freeze(arr); // 變量arr不可更改 4 arr.push(5); // 報錯:不能添加屬性
Object.definePropperty也能夠實現規定變量的不可更改ip
1 const obj = { key: 'chris', vlaue: 'person' }; 2 Object.defineProperty(obj, 'key', { 3 configurable: false, // 不可刪除 4 writable: false, // 不可寫 5 });