JS专题系列之Object.freeze
2022-10-08 本文已影响0人
DY_alley
一、什么是Object.freeze
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;
- 冻结了一个对象则不能向这个对象添加新的属性
- 不能删除已有属性
- 不能修改该对象已有属性的可枚举性、可配置性、可写性,
- 以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改
- freeze() 返回和传入的参数相同的对象
我们都知道const 定义基本数据类型这个值是不能被修改的。那么我们用const定义对象,对象可以被修改吗?
const a = 1;
a = 10; // Assignment to constant variable.
const obj = {
name: 'alley';
}
obj.name = 'dy_alley';
console.log(obj.name) ; // dy_alley
二、Object.freeze基本使用
var obj = {
name:'alley',
age:19,
sex:'男'
}
obj.__proto__.habit = '运动';
Object.freeze(obj);
// 不能添加新属性
obj.address = '北京'
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能删除原有属性
delete obj.age
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能修改已有属性的值
obj.name = 'dy_alley'
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能修改原型
obj.__proto__ = '随便什么值'
console.log(obj.__proto__) // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}
// 不能修改已有属性的可枚举性、可配置性、可写性
Object.defineProperty(obj,'name',{ // TypeError: Cannot redefine property: address
enumerable: false,
configurable: false,
writable: true
})
三、冻结数组
var arr = [1,2,3,4,5,6];
Object.freeze(arr);
arr[0] = 'alley';
console.log(arr); // [ 1,2,3,4,5].
四、深度冻结
Object.freeze只能进行浅冻结,如果对象里面有对象的情况下则无法冻结
var obj = {
name:'alley',
info: {
age:19,
sex:'男'
}
}
Object.freeze(obj);
obj.name = 'dy_alley';
obj.info.age = 20;
console.log(obj); // {name:'alley',info:{age:20,sex:'男'}};
通过递归来进行深度冻结
function deepFreeze(obj) {
/*
Object.getOwnPropertyNames()与Object.keys()的区别:
Object.getOwnPropertyNames返回的是对象中所有自己的属性;
Object.keys(obj)则返回的对象中所有自己的属性,也就是属性下的 enumerable: true 的属性
const obj = {};
Object.defineProperties(obj, {
name: {enumerable: true, value: 'alley'},
age: {enumerable: false, value: 25},
})
console.dir(Object.keys(obj))
console.dir(Object.getOwnPropertyNames(obj))
输出
> Array ["name"]
> Array ["name", "age"]
*/
var propsNames = Object.getOwnPropertyNames(obj);
propsNames.forEach((item)=>{
var props = obj[item];
if(props instanceof Object && props !==null) {
deepFreeze(props);
}
})
return Object.freeze(obj);
}
五、Object.freeze原理
模拟Object.freeze原理主要用到了2个方法, Object.definedProperty()、Object.seal()
Object.definedProperty方法可以定义对象属性的特性
Object.seal 可以让对象不能被扩展