幾種特殊定義對象
幾種特殊定義對象
禁止對象屬性擴展密封對象凍結對象
對象常量屬性
禁止屬性擴展
密封對象
凍結對象
禁止對象屬性擴展、密封對象、凍結對象
對象常量屬性
概念:將屬性的writable和configurable設置為false;
//將屬性的writable和configurable設置為false
var damu={};
Object.defineProperty(damu,"wife",{
value:"fbb"
})
Object.defineProperty(damu,"wife",{
value:"fbb2"
});
//無法更改,無法刪除。可以添加
//console.log(damu);//報錯,Cannot redefine property
damu.wife="damu"
delete damu.wife;
console.log(damu);//{wife: "fbb"}
damu.wife2="fbb2";
console.log(damu);//{wife2: "fbb2", wife: "fbb"}
禁止屬性擴展
概念
如果一個對象可以添加新的屬性,則這個對象是可擴展的,讓這個對象變的不可擴展,也就是不能再有新的屬性;
由於屬性描述符是對屬性的管理,所以想禁止對象擴展,不能使用屬性描述符來控制,而是需要調用其他的對象的方法。
兩種有關對象屬性擴展的對象方法:
Object.isExtensible 方法:Object.isExtensible() 方法判斷一個對象是否是可擴展的(是否可以在它上面添加新的屬性)。
語法: Object.isExtensible(obj)
參數: obj 需要檢測的對象;
默認情況下,創建的對象默認是可擴展
//新對象默認是可擴展的無論何種方式創建的對象
//使用的是字面量方式
var empty = {a:1};
console.log(Object.isExtensible(empty) === true);//true
//等價於 使用屬性描述符
empty = Object.create({},{
"a":{
value : 1,
configurable : true,//可配置
enumerable : true,//可枚舉
writable : true//可寫
}
});
console.log(Object.isExtensible(empty) === true);//true
//創建屬性的方式
var damu={};
Object.defineProperty(damu,"wife",{
value:"fbb"
})
console.log(Object.isExtensible(damu) === true);//true
Object.preventExtensions 方法:方法讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性,並且返回原對象。
語法:Object.preventExtensions(obj);
參數:obj 將要變得不可擴展的對象;
var damu = {};
Object.defineProperty(damu,'wife',{
value:'lbb'
});
console.log(damu);//{wife: "lbb"}
Object.preventExtensions(damu);
// damu.age = 18;
// console.log(damu);//{wife: "lbb"}
(function fail(){
"use strict";
damu.d = "4";//throws a TypeError
})();
console.log(damu);//Cannot add property d, object is not extensible
描述:
如果一個對象可以添加新的屬性,則這個對象是可擴展的。preventExtensions 可以讓這個對象變的不可擴展,也就是不能再有新的屬性。
需要注意的是不可擴展的對象的屬性通常仍然可以被刪除。
嘗試給一個不可擴展對象添加新屬性的操作將會失敗,不過可能是靜默失敗(默認情況),也可能會拋出 TypeError 異常(嚴格模式)。
注意:Object.preventExtensions 只能阻止一個對象不能再添加新的自身屬性,仍然可以為該對象的原型添加屬性。
密封對象
概念:
密封對象是指那些不可擴展的,且所有自身屬性都不可配置的(non-configurable)對象。
或者可以說,密封對象是指那些不能添加新的屬性,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫性,但可能可以修改已有屬性的值的對象。
可用方法:在禁止對象擴展(Object.preventExtensions(obj);的基礎上把現有屬性的configurable都調整為false;
//設置對象即使不可擴展又不可配置
var damu = {};
Object.defineProperty(damu,'wife',{
value:'lbb'
//此時默認的configurable和writable都為false的。
});
console.log(damu);//{wife: "lbb"}
Object.preventExtensions(damu);
damu.age = 18;
delete damu.wife;//{wife: "lbb"}
console.log(damu);//{wife: "lbb"};
//證明不可配置、不可擴展。但是這種設置的過程很麻煩,嘗試使用簡單的對象方法來設置密封對象。
兩種有關密封屬性的方法
Object.isSealed 方法:方法判斷一個對象是否是密封的(sealed)。
語法 :Object.isSealed(obj);
參數:obj 將要檢測的對象;
描述:如果這個對象是密封的,則返回 true,否則返回 false。
//使用Object.preventExtensions設置為不可擴展,再設置不可配置,則成為密封了。
var damu = {};
Object.defineProperty(damu,'wife',{
value:'lbb'
//此時默認的configurable和writable都為false的。
});
Object.preventExtensions(damu);
console.log(Object.isSealed(damu));//true
Object.seal() 方法:可以讓一個對象密封,並返回被密封后的對象。
語法:Object.seal(obj)
參數:obj 將要被密封的對象
var damu = {};
Object.defineProperty(damu,'wife',{
value:'lbb'
//此時默認的configurable和writable都為false的。
});
console.log(Object.getOwnPropertyDescriptor(damu,"wife"));//{value: "lbb", writable: false, enumerable: false, configurable: false}
Object.seal(damu);
console.log(Object.isSealed(damu));//true
//靜默失敗
damu.d = 'd';
delete damu.wife;
console.log(damu);//{wife: "lbb"}
console.log(Object.getOwnPropertyDescriptor(damu,"wife"))
描述:
通常情況下,一個對象是可擴展的(可以添加新的屬性)。
密封一個對象會讓這個對象變的不能添加新屬性,且所有已有屬性會變的不可配置。
屬性不可配置的效果就是屬性變的不可刪除,以及一個數據屬性不能被重新定義成為訪問器屬性,或者反之。但屬性的值仍然可以修改。
嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數據屬性轉換成訪問器屬性,結果會靜默失敗或拋出TypeError 異常(嚴格模式)。
不會影響從原型鏈上繼承的屬性。但 proto ( ) 屬性的值也會不能修改。
凍結對象
概念:
一個對象是凍結的(frozen)是指它不可擴展,所有屬性都是不可配置的(non-configurable),且所有數據屬性(data properties,指那些沒有取值器getter或賦值器setter的屬性)都是不可寫的(non-writable);
或則說 凍結對象是指那些不能添加新的屬性,不能修改已有屬性的值,不能刪除已有屬性,以及不能修改已有屬性的可枚舉性、可配置性、可寫性的對象。也就是說,這個對象永遠是不可變的;
可用方法:在密封對象(Object.seal(obj))的基礎上把現有屬性的writable都調整為false:
//在密封對象(Object.seal(obj))的基礎上把現有屬性的writable都調整為false
var damu = {};
Object.defineProperty(damu,'wife',{
value:'lbb',
//writable:true
});
//密封
Object.seal(damu);
//防擴展
Object.preventExtensions(damu);
damu.age = 18;
delete damu.wife;
damu.wife = 'zdy';
console.log(damu);//{wife: "lbb"};
兩種有關密封屬性的方法
Object.isFrozen 方法:方法判斷一個對象是否被凍結(frozen)。
語法: Object.isFrozen(obj)
參數:obj 被檢測的對象
Object.freeze() 方法:可以凍結一個對象。
語法:Object.freeze(obj);
參數:obj 將要被凍結的對象;
var damu = {wife:'lbb'};
console.log(Object.getOwnPropertyDescriptor(damu,"wife"));
//{value: "lbb", writable: true, enumerable: true, configurable: true}
//凍結對象
Object.freeze(damu);
console.log(Object.getOwnPropertyDescriptor(damu,"wife"));
//{value: "lbb", writable: false, enumerable: true, configurable: false}
damu.age = 18;
delete damu.wife;
damu.wife = 'zdy';
console.log(damu);//{wife: "lbb"}
描述:
凍結對象的所有自身屬性都不可能以任何方式被修改。
任何嘗試修改該對象的操作都會失敗,可能是靜默失敗,也可能會拋出異常(嚴格模式中)。
數據屬性的值不可更改,訪問器屬性(有getter和setter)也同樣(但由於是函數調用,給人的錯覺是還是可以修改這個屬性)。
如果一個屬性的值是個對象,則這個對象中的屬性是可以修改的,除非它也是個凍結對象。
//淺不變形
var damu={wifes:{wife1:"fbb",wife2:"lyf",wife3:"zdy"}};
damu.wifes.wife1="lbb";
console.log(damu);//wifes:{wife1: "lbb", wife2: "lyf", wife3: "zdy"}
//深層次凍結
var damu={
wifes:{wife1:"fbb",wife2:"lyf",wife3:"zdy"}
};
Object.freeze(damu);
//遍歷調用凍結方法,將對象屬性內的對象全部凍結。
for(item in damu){
Object.freeze(damu[item]);
}
damu.wifes.wife1="lbb";
console.log(damu);//wifes:{wife1: "fbb", wife2: "lyf", wife3: "zdy"}
————————————————
原文鏈接:https://blog.csdn.net/mutouafangzi/article/details/76637929