一、為什么需要引入防篡改對象?
1.
為什么?JavaScript 共享的本質一直是開發人員心頭的痛,因為任何對象都可以被在同一環境中運行的代碼修改。
2.
解決:我們可以手工設置每個對象屬性的
[[Configurable]]
、
[[Writable]]
、
[[Enumerable]]
、
[[Value]]
、
[[Get]]
以及
[[Set]]
特性,同樣我們可以設置對象的行為。
一、不可擴展的對象
1.
默認情況下,所有對象都是可以擴展的。也就是說,任何時候都可以向對象中添加屬性和方法
??????? var o = {
??????????? name :
"zhang"
??????? }
??????? o.age =
23
;
??????? alert(o.age);?????? //
23
2.
使用Object.preventExtensions()方法可以改變這個行為,讓你不能再給對象添加屬性和方法。
??????? var o = {
??????????? name :
"zhang"
??????? }
??????? alert(Object.isExtensible(o));? //
true
??????? Object.preventExtensions(o);
??????? o.age =
23
;
??????? alert(o.age);?????? // undefined
??????? alert(Object.isExtensible(o));? //
false
二、密封的對象
??? 密封對象不可擴展,而且已有成員的
[[Configurable]]
特性將被設置為
false
。這就意味著不能刪除屬性和方法,因為不能使用Object.defineProperty()把數據屬性修改為訪問器屬性,或者相反。屬性值是可以修改的。
??????? var o = {
??????????? name :
"zhang"
??????? }
??????? // alert(Object.isExtensible(o));?? //
true
??????? // alert(Object.isSealed(o));?? //
false
??????? // 不能添加屬性和方法
??????? Object.seal(o);
??????? o.age =
23
;
??????? // alert(o.age);??????? // undefined
??????? // 不能刪除屬性
??????? delete o.name;
??????? // alert(o.name);?????? // zhang
??????? // 可以修改已有屬性的值
??????? o.name =
"li"
;
??????? alert(o.name);
??????? alert(Object.isExtensible(o));? //
false
??????? alert(Object.isSealed(o));? //
true
三、凍結的對象
??? 凍結的對象既不可擴展,又是密封的,而且對象數據屬性的
[[Writable]]
特性會被設置為
false
。如果定義
[[Set]]
函數,訪問器屬性仍然是可寫的。
??????? var o = {
??????????? name :
"zhang"
??????? }
??????? // alert(Object.isExtensible(o));?? //
true
??????? // alert(Object.isSealed(o));?? //
false
??????? // alert(Object.isFrozen(o));?? //
false
??????? // 不能添加屬性和方法
??????? Object.freeze(o);
??????? o.age =
23
;
??????? // alert(o.age);??????? // undefined
??????? // 不能刪除屬性
??????? delete o.name;
??????? // alert(o.name);?????? // zhang
??????? // 不可以修改屬性
??????? o.name =
"li"
;
??????? // alert(o.name);
??????? alert(Object.isExtensible(o));? //
false
??????? alert(Object.isSealed(o));? //
true
??????? alert(Object.isFrozen(o));? //
true