Object.defineProperty(obj, prop, descriptor) 函數
descriptor的描述有兩種:數據描述符和存取描述符。 spa
數據描述符是一個具備值的屬性,該值多是可寫的,也可能不是可寫的。prototype
存取描述符是有getter-setter函數描述的屬性。 code
描述符必須是這兩種形式之一,不能同時是二者。對象
可同時具blog 有的鍵值繼承 |
configurable | enumerable | value | writable | get | set |
數據描述符 | yes | yes | yes | yes | no | no |
存取描述符 | yes | yes | no | no | yes | yes |
默認值 | false | false | undefined | false | undefined | undefined |
當writable屬性設置爲false時,該屬性被稱爲「不可寫」。它不能被從新分配。若是試圖寫入非可寫屬性,屬性不會改變,也不會引起錯誤。ip
enumerable定義對象的屬性是否能夠在for...in循環和Object.keys()中被枚舉。enumerable默認爲false,若是直接賦值的方式(o.d=4)建立對象的屬性,則這個屬性的enumerable爲true。get
o.propertyIsEnumerable('a'); 獲取對象的屬性是否可枚舉。 原型
configurable特性表示對象的屬性是否能夠被刪除,以及除value和writable特性外的其餘特性是否能夠被修改。
var o = {}; o.a = 1; // 等同於 :
Object.defineProperty(o, "a", { value : 1, writable : true, configurable : true, enumerable : true }); // 另外一方面,
Object.defineProperty(o, "a", { value : 1 }); // 等同於 :
Object.defineProperty(o, "a", { value : 1, writable : false, configurable : false, enumerable : false });
記住,這些選項不必定是自身屬性,若是是繼承來的也要考慮。爲了確認保留這些默認值,你可能要在這以前凍結 Object.prototype,明確指定全部的選項,或者經過 Object.create(null)將__proto__屬性指向null。
注意:在對象上設置值屬性時,若是原型上不存在這個屬性,那麼設置的值屬性在對象上。然而,若是原型上一個不可寫的屬性被繼承,那麼它仍會防止修改對象上的屬性。
function myclass() { } myclass.prototype.x = 1; Object.defineProperty(myclass.prototype, "y", { writable: false, value: 1 }); var a = new myclass(); a.x = 2; console.log(a.x);// 2
console.log(myclass.prototype.x); // 1
a.y = 2; // Ignored, throws in strict mode
console.log(a.y); // 1
console.log(myclass.prototype.y); // 1
參考博客: