preventExtensions
預設情況下,所有物件都是可擴充套件的。在呼叫preventExtensions
之後,將不能再往物件中新增屬性(嚴格模式報錯,非嚴格模式靜默失敗),對已有屬性沒有影響
let obj1 = {name: 'xiaohua'};
Object.preventExtensions(obj1);
obj1.name = 'xiaomei';
obj1.name //xiaomei 已有屬性可讀可寫
obj1.age=23
obj1.age // undefined,新增屬性靜默失敗
複製程式碼
seal
密封屬性;密封屬性不可擴充套件;而且已有成員的configurable屬性會被設定為false
let obj2 = {name: 'xiaohua'};
Object.seal(obj2);
Object.isExtensible(obj2) // false, 不可擴充套件
obj1.age=23
obj1.age // undefined,新增屬性靜默失敗
Object.getOwnPropertyDescriptor(obj2, 'name') // writable: true, enumerable: true, configurable: false
複製程式碼
freeze
凍結物件;凍結物件不可擴充套件且密封;而且已有成員的configurable及writable屬性會被設定為false
let obj3 = {name: 'xiaohua'};
Object.freeze(obj3)
Object.isExtensible(obj3) // false, 不可擴充套件
Object.isSealed(obj3) // true, 密封
Object.getOwnPropertyDescriptor(obj2, 'name') // writable: false, enumerable: true, configurable: false
複製程式碼
補充知識
兩種定義物件屬性的方式比較
使用obj = {age: 2}
定義物件的屬性,其writable,enumerable,configurable均為true
let obj = {age: 2};
Object.getOwnPropertyDescriptor(obj, 'age');
// value: 2, writable: true, enumerable: true, configurable: true
複製程式碼
Object.defineProperty(obj, prop, descriptor),使用defineProperty
定義物件的屬性,其中未定義的屬性預設為false
let obj2 = {};
Object.defineProperty(obj2, 'age', {value: 2});
Object.getOwnPropertyDescriptor(obj2, 'age');
// value: 2, writable: false, enumerable: false, configurable: false
Object.defineProperty(obj2, 'favourites', {value: 'js', writable: true});
Object.getOwnPropertyDescriptor(obj2, 'favourites');
// value: "js", writable: true, enumerable: false, configurable: false
複製程式碼
writable,enumerable,configurable
物件的資料屬性
writable:表示能否修改屬性的值。true時,可以重寫該屬性的值;屬性為false時,修改屬性的值在非嚴格模式下不會生效,嚴格模式下會報錯。
enumerable:表示能否通過for-in
或Object.keys()
迴圈返回屬性。true時可以訪問,false不可以訪問到
configurable:表示能否通過delete刪除屬性,能否通過Object.defineProperty()修改屬性的特性。值為true時可以delete並且可以修改,值為false時,表示不能從物件中刪除屬性。如果對這個屬性呼叫delete,則在非嚴格模式下什麼也不會,但是嚴格模式下會導致錯誤。而且,此時,再呼叫Object.defineProperty()方法修改除writable之外的特性,都會導致錯誤。
let person = {};
Object.defineProperty(person, 'name', {value: 'xiaohua', writable: true, enumerable: true});
// writable: true, enumerable: true, configurable: false
Object.defineProperty(person, 'name', { enumerable: false}); // 報錯
Object.defineProperty(person, 'name', { writable: false}); // configurable為false, 且writable為true時,可以修改writable
// writable: false, enumerable: true, configurable: false
Object.defineProperty(person, 'name', { writable: true}); // 報錯
複製程式碼
value:表示這個屬性的資料值,預設為undefined
在呼叫Object.defineProperty()方法時,以上屬性預設 false
訪問器屬性
訪問器屬性不包含資料值-它們是一對getter和setter函式。訪問器屬性有如下4個特性
configurable: 同上
enumerable: 同上
get:在讀取屬性時呼叫的函式
set:在寫入屬性時呼叫的函式