一、Object.defineProperty的作用
用來給對象新增屬性,和修改對象中的屬性。
二、JS對象中的描述符
js對象中兩種屬性描述符:數據描述符和存取描述符(訪問描述符)。
注意事項:
1、數據描述符和存取描述符都具備configurable、enumerable屬性。
2、描述符不具備value,writetable,set和get任意一個關鍵字都被認作一個數據描述符。
3、(value或writetable)和(get和set)不能同時存在,然后只要定義了set和get或其中一個都是一個存取描述符(描述符只能是其中一種)。

三、Object.defineProperty的使用
var o = {}; // 創建一個新對象
// 在對象中添加一個屬性與數據描述符的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
// 對象o擁有了屬性a,值為37
// 在對象中添加一個屬性與存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});
o.b = 38;
// 對象o擁有了屬性b,值為38
1、writable、enumerable、configurable為false的情況
wirtable:變量不可再被重新賦值
enumerable: 變量不能在遍歷器例如for...in和Object.keys()中被讀取出來,不可被遍歷
configurable:變量不可配置,定義為false之后,不能再為該變量定義配置否則報錯。變量被刪除(delete)、修改都會無效。
2、如果對象的屬性是存取描述符,只會調用定義了的set和get(configurable、enumrable)
在給一個對象屬性做賦值操作,在讀取屬性值時,這個賦值操作賦值的值會被忽略,會去調用定義的get方法的值
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature = "67"
console.log(arc.temperature); // undefined
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
四、關於給對象定義set/get方法
vue中可以在computed中給變量定義get/set方法(https://cn.vuejs.org/v2/guide/computed.html),結合v-model雙向數據綁定變量有很多的用處,比如官網的名字的名和姓的拼接。在子組件中我們想要修改父組件傳來的值並及時在dom中渲染的時候。

computed中給變量定義set/get方法並不是vue中特有的方法,es5中支持了Object.defineProperty,在Object.defineProperty可以給對象的屬性設置為訪問描述符類型,定義set/get方法。我們除了通過這個方法給屬性定義set/get ,還可以通過對象文字語法來定義。
var myObject = {
get a() {
return 2
}
}
myObject.a = 3
console.log(myObject.a)//2
console.log(myObject.b)//undefined
參考資料:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
http://imweb.io/topic/56d40adc0848801a4ba198ce
