一、object.freeze()函數的基本概念
object.freeze()是一種JavaScript函數,可以防止對象被修改,使其變得不可變。當我們使用object.freeze()函數時,該對象本身以及其屬性都變成只讀的,這意味著不能再添加新屬性,不能刪除或修改現有屬性。
下面是object.freeze()函數的簡單示例:
const obj = { name: "Tom", age: 20 }; // 使用freeze函數凍結對象 Object.freeze(obj); // 嘗試修改對象,但沒有任何輸出 obj.age = 25; console.log(obj.age); // 輸出 20
從上面的示例中可以看出,當我們使用object.freeze()函數時,obj的age屬性無法修改。這個函數將禁止對對象進行任何更改,這是很安全的。當我們想要創建一個不可變的對象時,這是非常有用的。
二、object.freeze()函數與淺凍結
當我們調用object.freeze()函數對對象進行凍結時,僅僅是將該對象的屬性和值變為只讀,但是並沒有對該對象的引用地址進行變更。這意味著我們仍然可以修改該對象的屬性,例如添加、刪除或修改。
可以看下面的示例:
const person = { name: { first: "Tom", last: "Jerry" }, age: 20 }; // 凍結person對象 Object.freeze(person); // 嘗試修改對象 person.age = 25; console.log(person.age); // 添加屬性,但沒有任何輸出 person.gender = "male"; console.log(person.gender); // 修改屬性,但也沒有任何輸出 person.name.first = "Jim"; console.log(person.name.first); // 輸出 "Jim" // 再次嘗試凍結 Object.freeze(person.name); // 嘗試修改屬性 person.name.first = "Lily"; console.log(person.name.first); // 輸出 "Jim",沒有被更改
從示例代碼中可以看出,嘗試修改屬性和添加新屬性都沒有任何輸出。但是嘗試修改對象內包含的對象屬性時,仍然可以修改。
因此,我們也可以使用object.freeze()函數來對對象內部屬性進行凍結。我們只需迭代每個屬性並使用該函數對其進行凍結即可,這稱為「深凍結」。
三、object.freeze()函數與深凍結
深凍結是指將對象及其所有子對象凍結的過程。這個過程需要以遞歸的形式進行,以確保所有對象都被凍結。
下面是一個示例代碼,演示如何使用遞歸對對象進行深凍結:
const person = { name: { first: "Tom", last: "Jerry" }, age: 20 }; // 定義深凍結函數 function deepFreeze(object) { // 對象本身進行凍結 Object.freeze(object); // 迭代所有屬性 Object.getOwnPropertyNames(object).forEach(function(prop) { // 如果屬性是一個對象,則遞歸調用函數進行深凍結 if (object.hasOwnProperty(prop) && object[prop] !== null && (typeof object[prop] === "object" || typeof object[prop] === "function") && !Object.isFrozen(object[prop])) { deepFreeze(object[prop]); } }); return object; } // 對person對象進行深凍結 deepFreeze(person); // 嘗試修改對象內部屬性,但沒有任何輸出 person.age = 25; console.log(person.age); // 嘗試修改對象內部屬性,但也沒有任何輸出 person.name.first = "Lily"; console.log(person.name.first); // 輸出 "Tom"
從上面的代碼中可以看出,深凍結函數被定義為deepFreeze(),而該函數將遞歸地迭代每個屬性並使用object.freeze()函數進行凍結。在嘗試修改對象屬性時,沒有任何輸出。
四、object.freeze()函數的應用場景
以下是object.freeze()函數的兩個常用場景。
1、創建不可變的對象
在JavaScript中,對象屬性是可被修改的(除了有些常量對象)。如果我們想創建一個對象,這個對象的屬性不能被更改,這時候我們可以使用object.freeze()函數。
const person = { name: "Tom", age: 20 }; // 凍結對象 Object.freeze(person); // 添加新屬性,但沒有任何輸出 person.gender = "male"; console.log(person.gender);
2、確保代碼中的常量值不會更改
使用常量作為開發中的變數是很常見的。例如,在使用React等一些前端框架時,固定的字元串常量被用作事件類型,這些常量不應被修改。當變數被處理後,我們不能使其變為之前的狀態。因此,我們可以使用object.freeze()函數來凍結常量的值。
const events = { CHANGE: "change", COMPLETE: "complete", ERROR: "error" }; // 凍結常量 Object.freeze(events); // 嘗試修改常量,沒有任何輸出 events.ERROR = "ERROR"; console.log(events.ERROR);
五、結論
object.freeze()函數可以將一個對象變為不可變的對象,以及凍結對象的屬性和值,使其變得只讀無法修改。當使用遞歸形式時,它還可以對對象的所有子對象進行深凍結。除了作為創建不可變對象之外,另一個常見的用途是確保整個代碼中的常量值不會被修改。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/197126.html