<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
物件不變性在任何程式語言中都是一個重要的概念。它會限制物件修改並防止不需要的更改。簡而言之,物件的不變性就是將它的狀態變為唯讀的,下面就來看看在 JavaScript 中的物件不變性。
在JavaScript
中,一個物件可以有一個或多個屬性。每個屬性都是一個鍵值對,
下面是一個物件:
const user = { name: 'CUGGZ', age: 24, }
這裡使用const
關鍵字定義了一個物件,它具有兩個屬性。預設情況下,物件是可變的,也就是說,我們可以給物件新增新屬性,修改現有屬性或者刪除已有屬性。而在某些情況下,我們可能希望物件是不可變的,即不能新增新屬性,也不能修改和刪除已有屬性。
顧名思義,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
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
你是否會認為,使用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關鍵字僅僅是提供了賦值的不變性,而不會提供值的不變性(對於物件來說)。
本文簡單介紹了兩種可以用於使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 物件不變性內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45