標籤:改變 可變對象 null typeof hang div for turn 方法
預設情況下,JavaScript 中的對象是可變的。我們可以更改原始值(字串,數字等)和對象。我們來看看這個對象:
let obj = { num: 10, obj: { content: "mutable object" }}
你可以輕鬆地改變它:
obj.num = 5;obj.obj = { content: "changed!" } console.log(obj); // {// num: 5,// obj: {// content: "changed!"// }// }
非常明確是吧?那麼,我們有什麼辦法使對象不可變呢?
1、讓我們試用 const !
很好的嘗試,但是不起作用。如果你嘗試一下,你會發現:這種辦法根本就不起作用。const 關鍵字只是修改了某個變數名和其值之間的連結,而不是實際值。您仍然可以像上面所做的那樣在 const 對象中更改這兩個原始值和對象。例如:
const obj = { num: 10, obj: { content: "mutable object" }} obj.num = 5;obj.obj = { content: "changed!" } console.log(obj); // {// num: 5,// obj: {// content: "changed!"// }// }
2、繼續嘗試:Object.freeze()。
有很多關於 ES2015 新特性的文章和討論。我們知道 ES2015 比 ES5 更好。例如,我們可以使用一個Object 方法來實現我們的目的:Object.freeze()。該方法使對象的原始屬性不可變。我們把這個方法應用到我們原來的 obj 對象上:
Object.freeze(obj);obj.num = 5;obj.obj = { content: "changed!" } console.log(obj); // {// num: 10,// obj: {// content: "changed!"// }// }
結果比原先的嘗試稍後好一點,原始值現在已經修複,不可更改,但是我們仍然可以更改嵌套對象。
3、最終解決方案
為了使對象完全不可變,我們還需要freeze()所有的嵌套對象。例如:
function deepFreeze(obj) { var propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function(name) { var prop = obj[name]; if (typeof prop == ‘object‘ && prop !== null) { deepFreeze(prop); } }); return Object.freeze(obj);}
使用這個函數,現在我們可以建立完全不可變的對象:
deepFreeze(obj);obj.num = 5;obj.obj = { content: "changed!" } console.log(obj); // {// num: 10,// obj: {// content: "mutable object"// }// }
JavaScript 中的不可變對象(Immutable Objects)