文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript对象不变性介绍

2024-04-02 19:55

关注

1. 基本概念

对象不变性在任何编程语言中都是一个重要的概念。它会限制对象修改并防止不需要的更改。简而言之,对象的不变性就是将它的状态变为只读的,下面就来看看在 JavaScript 中的对象不变性。​

JavaScript中,一个对象可以有一个或多个属性。每个属性都是一个键值对,

下面是一个对象:

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

这里使用const关键字定义了一个对象,它具有两个属性。默认情况下,对象是可变的,也就是说,我们可以给对象添加新属性,修改现有属性或者删除已有属性。而在某些情况下,我们可能希望对象是不可变的,即不能添加新属性,也不能修改和删除已有属性。

2. Object.freeze()

顾名思义,freeze() 就是用来冻结对象的。只需要将不想被更改的对象传递给它,就会返回该对象的不可变版本:

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

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

这时,新的对象就不可变了,相当于被冻结了。​

JavaScript了,提供了一个Object.isFrozen(),它可以用来判断一个对象是否被冻结:

Object.isFrozen(user)  // false
Object.isFrozen(freezeUser)  // true

需要注意的是, Object.freeze() 方法不会影响嵌套对象,对于嵌套对象,冻结后仍然是可以操作的:

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

可以看到,使用Object.freeze() 方法冻结的对象,age是不可以更改的,但是嵌套对象的number属性还是可以修改的。如果需要冻结嵌套对象使其不可变,就需要使用循递归来逐级冻结,下面是一个简单的递归冻结实现:

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

deepFreeze(user);

Object.freeze()方法除了可以用来冻结对象以外,还可以用于冻结数组,使其不可变:

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

3. Object.seal()

Object.seal() 顾名思义就是密封对象,它是另一种使对象不可变的方法。相对于freeze(),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}

可以看到,我们识图删除对象中的name属性,删除失败;而修改已有的age属性,修改成功。​

Object.seal()方法和Object.freeze()一样,对于嵌套的对象,是无法实现不可变的,如果想要实现,同样要使用递归来一层层来密封对象。​

JavaScript同样提供了一个Object.isSealed() 方法来确认对象的密封状态:

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

4. 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}

而如果我们给user重新赋值,那么就会报错了:

Uncaught TypeError: Assignment to constant variable.

因此,const关键字仅仅是提供了赋值的不变性,而不会提供值的不变性(对于对象来说)。

5. 总结

本文简单介绍了两种可以用于使JavaScript不可变的方法。简而言之,Object.seal()方法会阻止更新、删除和向对象添加新属性,Object.seal()只会阻止添加和删除属性。、

除此之外,JavaScript还提供了一个Object.preventExtensions()方法,该方法可以让一个对象变的不可扩展,也就是永远不能再添加新的属性。

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

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

最后来看看它们三个的对比:

方法/操作读取创建更新删除
Object.freeze()✔️
Object.seal()✔️✔️
Object.preventExtensions()✔️✔️✔️

到此这篇关于JavaScript 对象不变性介绍的文章就介绍到这了,更多相关JavaScript 对象不变性内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯