1. 程式人生 > 實用技巧 >JavaScript 物件的防篡改preventExtensions/seal/freeze

JavaScript 物件的防篡改preventExtensions/seal/freeze

	// 首先宣告三個物件
	const a = {v: 1};
	const b = {v: 1};
	const c = {v: 1};
	
	/*
	Object.preventExtensions() 方法讓一個物件變的不可擴充套件,也就是永遠不能再新增新的屬性。
	
	Object.seal() 方法封閉一個物件,阻止新增新屬性並將所有現有屬性標記為不可配置。當前屬性的值只要原來是可寫的就可以改變。
	
	Object.freeze() 方法可以凍結一個物件。一個被凍結的物件再也不能被修改;凍結了一個物件則不能向這個物件新增新的屬性,不能刪除已有屬性,不能修改該物件已有屬性的可列舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個物件後該物件的原型也不能被修改。freeze() 返回和傳入的引數相同的物件。
	*/
	Object.preventExtensions(a);
	Object.seal(b);
	Object.freeze(c);
	
	/*
	Object.getOwnPropertyDescriptors() 用來獲取一個物件的所有自身屬性的描述符(結構是否可改變, 是否可列舉, 屬性是否可更改)。
	* 1.configurable:表示能否通過delete刪除此屬性,能否修改屬性的特性,或能否修改把屬性修改為訪問器屬性,如果直接使用字面量定義物件,預設值為true;
	* 2.enumerable: 表示該屬性是否可列舉,即是否通過for-in迴圈或Object.keys()返回屬性,如果直接使用字面量定義物件,預設值為true;
	* 3.writable: 能否修改屬性的值,如果直接使用字面量定義物件,預設值為true;
	* 4.value: 該屬性對應的值,預設為undefined。
	* */
	console.log(Object.getOwnPropertyDescriptors(a)); // => {v: {value: 1, writable: true, enumerable: true, configurable: true}}
	console.log(Object.getOwnPropertyDescriptors(b)); // => {v: {value: 1, writable: true, enumerable: true, configurable: false}}
	console.log(Object.getOwnPropertyDescriptors(c)); // => {v: {value: 1, writable: false, enumerable: true, configurable: false}}
	
	// 下面開始修改物件
	a.v = 2;
	a.k = 0;
	
	b.v = 2;
	b.k = 0;
	
	c.v = 2;
	c.k = 0;
	
	console.log(a); // => {v: 2} // 可修改不可新增
	console.log(b); // => {v: 2} // 可修改不可新增
	console.log(c); // => {v: 1} // 不可修改不可新增
	
	/*
	Object.isExtensible() 方法判斷一個物件是否是可擴充套件的(是否可以在它上面新增新的屬性)。
	* */
	console.log(Object.isExtensible(a)); // => false
	console.log(Object.isExtensible(b)); // => false
	console.log(Object.isExtensible(c)); // => false
	
	// 再來使用delete操作物件
	
	delete a.v;
	delete b.v;
	delete c.v;
	
	console.log(a); // => {} // 可刪除
	console.log(b); // => {v: 2} // 不可刪除
	console.log(c); // => {v: 1} // 不可刪除
	
	/*
	結論
	* preventExtensions 可刪除和修改源屬性,不可新增新屬性
	* seal 可修改但是不可刪除源屬性,不可新增新屬性
	* freeze 不可修改和源屬性,不可新增新屬性
	* */