[JavasSript] 關於Object.freeze的淺凍結及應對方法

Leisure Rife
5 min readMay 8, 2021

--

Canva

本篇文章屬個人見解,若有錯誤部分,請不吝指教

概要

在使用JavaScript的Function的時候,還是要多仔細看官方文件,不然很容易就會踩雷,譬如說最近就發現Object.freeze只是淺凍結(Shallow Freeze)而已。

首先,我們先來看一下官方的說明

Note that values that are objects can still be modified, unless they are also frozen.

所以也就是說如果物件底下的參數是物件的話,那此物件仍然可以被修改,除非這個物件也被凍結。簡單來說的話,Object.freeze只能凍結第一層,第二層之後就凍結不住了。下面我們就用簡單的程式碼來進行解說。

解說

假設今天有一個成績單的物件,裡面記載著成績單的月份以及數學和歷史的兩個科目成績。

const transcript = {
month: 'May',
scoreList: {
math: 70,
history: 49,
}
};

Object.freeze凍結第一層

我們嘗試去更改第一層的參數,結果也證實無法更動到第一層的參數。如果使用strict mode的話,則會跳出錯誤。

Object.freeze(transcript);transcript.month = 'March';
transcript.scoreList = {};
console.log(transcript);
//Output:
Object { month: "May", scoreList: Object { math: 70, history: 49 } }

Object.freeze凍結不到第二層

這一次我們嘗試去更改第二層的數學成績,就可以發現數學成績是可以被更改的。所以Object.freeze是凍結不到第二層的。

Object.freeze(transcript);transcript.month = 'March';
transcript.scoreList = {};
transcript.scoreList.math = 60;
console.log(transcript);
//Output:
Object { month: "May", scoreList: Object { math: 60, history: 49 } }

應對方法

那如果遇到需要深凍結的情況的時候,要怎麼去對應呢?

1.第二層也用Object.freeze凍結

const transcript = {
month: 'May',
scoreList: {
math: 70,
history: 49,
}
};
Object.freeze(transcript);
Object.freeze(transcript.scoreList);
transcript.month = 'March';
transcript.scoreList = {};
transcript.scoreList.math = 123;
console.log(transcript);
//Output:
Object { month: "May", scoreList: Object { math: 70, history: 49 } }

2.使用Lodash的CloneDeep來創立新的物件,避免原本所參照的物件被更動

3.使用官方的deepFreeze

4.使用民間高手的Deep Freeze寫法

可以用Object.assign來解決嗎?

不行,Object.assign的第二層也會被更改。

範例程式碼

const objSource = { number1: 1, object1: { number2 :2 } }
const objNew = Object.assign({}, objSource)
objSource.number1 = 2
objSource.object1.number2 = 3
console.log('objSource', objSource)
console.log('objNew', objNew)

// Output
> "objSource" Object { number1: 2, object1: Object { number2: 3 } }
> "objNew" Object { number1: 1, object1: Object { number2: 3 } }

參考連結

--

--

Leisure Rife
Leisure Rife

Written by Leisure Rife

尋找著在忙忙碌碌的世界中,最適合自己的生活,也或許不斷的移動城市是我的生活方式

No responses yet