1. 測試對(duì)象
let like = Symbol("like");
let obj = {
name: "Lawson",
age: 18,
innerObj: {
innerName: "innerName",
innerAge: 30,
},
[like]: {
symbolName: "SymbolName",
},
};
Object.defineProperty(obj, "myProp", {
writable: false,
enumerable: false,
configurable: true,//如果為false,則描述屬性不能被配置
value: "myPropVal",
});
let objRet = Object.freeze(obj);
2. 被凍結(jié)對(duì)象特點(diǎn)
- 【不能】添加新的屬性
obj.sex = '男'
console.log(obj.sex);//undefined
- 【不能】刪除已有屬性
delete obj.age;
console.log(obj.age);//18
- 【不能】修改已有屬性的值
obj.age = 20
console.log(obj.age);//18
- 【不能】修改該對(duì)象已有屬性的可枚舉性
enumerable
蒋纬、可配置性configurable
蜀备、可寫性writable
console.log(Object.getOwnPropertyDescriptor(obj, 'myProp'));
/* {
value: 'myPropVal',
writable: false,
enumerable: false,
configurable: false //已經(jīng)不能被配置了
} */
- 【不能】修改原型
obj.__proto__ = Object.create(null); //Uncaught TypeError: #<Object> is not extensible
console.log(obj.__proto__);
- 返回和傳入的參數(shù)相同的對(duì)象(同一堆地址)
//隱式轉(zhuǎn)換荒叶,相同類型Object只比較堆地址
console.log(objRet == obj);//true
3. 深凍結(jié)
obj.innerObj.innerAge = 29;
console.log(obj.innerObj.innerAge);//29 被成功修改些楣,淺凍結(jié)失效
3.1 通用代碼
function deepFreeze(obj) {
// 取回定義在obj上的屬性名
var propNames = Reflect.ownKeys(obj);
// 在凍結(jié)自身之前凍結(jié)屬性
propNames.forEach(function (name) {
var prop = obj[name];
// 如果prop是個(gè)對(duì)象,凍結(jié)它
if (typeof prop == "object" && prop !== null) {
deepFreeze(prop);
}
});
// 凍結(jié)自身(no-op if already frozen)
return Object.freeze(obj);
}
測試
deepFreeze(obj);
obj.innerObj.innerAge = 29;
console.log(obj.innerObj.innerAge); //30
obj[like].symbolName = "Shery";
console.log(obj[like].symbolName); //SymbolName
4. 使用場景
- 復(fù)雜枚舉類
參考文章:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze