对象不变性

32 阅读1分钟

基本概念

对象不变性就是js中,限制对象的修改,包括增加/删除属性,更改属性值。

API

Object.freeze()

冻结对象,只要将想冻结的对象传给该方法,就会生成一个对象的冻结版本,生成的冻结对象,不能增删属性,不能修改其属性值

const user = {
	name: 'CUGGZ',
        age: 24,
}
const freezeUser = Object.freeze(user)
freezeUser.age = 18
console.log(freezeUser)   // {name: 'CUGGZ', age: 24}

判断一个对象是否是冻结对象

Object.isFrozen(freezeUser)   // true

嵌套对象不冻结

const user = {
  name: 'CUGGZ',
  age: 24,
  article: {
    title: 'learn javascript',
    number: 1234
  }
}

const freezeUser = Object.freeze(user);
freezeUser.age = 18
freezeUser.article.number = 666;
console.log(freezeUser.age)             // 24
console.log(freezeUser.article.number); // 666

嵌套对象冻结递归实现:

const deepFreeze = obj => {
  Object.keys(obj).forEach(prop => {
    if (typeof obj[prop] === 'object') {
    	deepFreeze(obj[prop]);
    }
  });
  return Object.freeze(obj);
};

deepFreeze(user);

冻结数组

const number = [1, 2, 3, 4, 5];
const freezeNumber = Object.freeze(number);
freezeNumber.push(6); // 报错,VM210:3 Uncaught TypeError: Cannot add property 5, object is not extensible

Object.seal()

密封属性,不允许增/删属性,允许修改属性值

const user = {
  name: 'CUGGZ',
  age: 24,
}

const sealUser = Object.seal(user);
sealUser.age = 18;
delete sealUser.name;
console.log(sealUser)  // {name: 'CUGGZ', age: 18}

判断一个对象是否是密封对象

Object.isSealed(user)      // false
Object.isSealed(sealUser)  // true

嵌套对象需递归密封。

const声明的对象?

  • const声明的对象,可以增删改查属性,因为虽然const是常量,但是在对象中,只是内存地址不能变,而对内存的真实内容可以修改。
  • 但是不能整体赋值,相当于修改了内存地址
const user = {
	name: 'CUGGZ',
  age: 24,
}

delete user.age;
user.height = 180;
user.name = 'hello';
console.log(user);  // {name: 'hello', height: 180}

Object.preventExtensions()

生成一个不可扩展的对象,不可扩展,指属性不能增加

const user = {
	name: 'CUGGZ',
  age: 24,
}

const newUser = Object.preventExtensions(user);
newUser.height = 180;
console.log(newUser);  // {name: 'CUGGZ', age: 24}

对比

image.png