對(duì)象凍結(jié)
這是使用Object.freeze的方法:
let objectToFreeze = {
age: 28,
name: "Damien",
pets: ["Symba", "Hades", "Kiwi"],
sibling: {
age: 25,
name: "Corentin",
},
};
Object.freeze(objectToFreeze);
Object.freeze將對(duì)象作為參數(shù)。請(qǐng)注意,它修改了您作為參數(shù)傳遞的對(duì)象。它不會(huì)復(fù)制對(duì)象并創(chuàng)建一個(gè)新對(duì)象。
那么這對(duì)物體意味著什么呢?
- 您不能向?qū)ο筇砑有聦傩?/li>
- 如果屬性本身不是對(duì)象或數(shù)組,則無(wú)法修改。(稍后會(huì)詳細(xì)介紹)
- 您不能從對(duì)象中刪除屬性
let objectToFreeze = {
age: 28,
name: "Damien",
pets: ["Symba", "Hades", "Kiwi"],
sibling: {
age: 25,
name: "Corentin",
},
};
Object.freeze(objectToFreeze);
delete objectToFreeze.age;
objectToFreeze.name = "Ben";
objectToFreeze.pets.push("Grenade");
objectToFreeze.sibling.age = 26;
objectToFreeze.lastName = "Cosset";
根據(jù)我剛才給您的描述,您應(yīng)該猜測(cè)該對(duì)象現(xiàn)在的外觀:
console.log(objectToFreeze)
// objectToFreeze :
{ age: 28,
name: 'Damien',
pets: [ 'Symba', 'Hades', 'Kiwi', 'Grenade' ],
sibling: {
age: 25,
name: 'Corentin'
}
}
該刪除失敗,修改名稱屬性失敗并添加lastName的失敗財(cái)產(chǎn)。但是修改數(shù)組是可行的。
注意:如果您不在嚴(yán)格模式下,它將以靜默方式失敗。在嚴(yán)格模式下,您將收到TypeErrors
"use strict";
let objectToFreeze = {
age: 28,
name: "Damien",
pets: ["Symba", "Hades", "Kiwi"],
sibling: {
age: 25,
name: "Corentin",
},
};
Object.freeze(objectToFreeze);
delete objectToFreeze.age;
拋出這個(gè):
淺凍結(jié)
當(dāng)我們稱為Object.freeze時(shí),我們所擁有的只是一個(gè)淺凍結(jié)。我們僅凍結(jié)直接附加到對(duì)象的對(duì)象。不關(guān)心對(duì)象和數(shù)組內(nèi)部的屬性。
為了使整個(gè)對(duì)象以及其中的所有內(nèi)容不可變,您必須在每個(gè)元素上調(diào)用Object.freeze()。這是您可以執(zhí)行此操作的一種方法:
let allYouCanFreeze = () => {
// Retrieve the properties names
let propNames = Object.getOwnPropertyNames(obj);
// Loop through the properties
// If typeof is "object", meaning an array or object, use recursion to freeze its contents.
for (let name of propNames) {
let value = obj[name];
obj[name] =
value && typeof value === "object" ? allYouCanFreeze(value) : value;
}
// Finally, freeze the main object
return Object.freeze(obj);
};
讓我們?cè)诘谝粋€(gè)對(duì)象上使用它:
let objectToFreeze = {
age: 28,
name: "Damien",
pets: ["Symba", "Hades", "Kiwi"],
sibling: {
age: 25,
name: "Corentin",
},
};
allYouCanFreeze(objectToFreeze);
// Now we can't touch the pets array and the sibling object
objectToFreeze.age = 26; // Now, fails.
objectToFreeze.pets.push("Grenade"); // Now, fails
大!現(xiàn)在,我們的兄弟對(duì)象和pets數(shù)組無(wú)法修改。
對(duì)象凍結(jié)
要知道對(duì)象是否被凍結(jié),可以使用Object.isFrozen():
Object.isFrozen(objectToFreeze); // === true
let unfrozenObj = { a: 42 };
Object.isFrozen(unfrozenObj); // === false
物體密封
像Frozen方法一樣,Object.seal()也將對(duì)象作為參數(shù)。Object.seal是Object.freeze的較軟版本。
- 您不能刪除或向?qū)ο筇砑釉亍?/li>
- 您可以修改現(xiàn)有屬性。
let objectToSeal = {
name: "Damien",
age: 28,
pets: ["Symba", "Hades", "Kiwi"],
sibling: {
age: 25,
name: "Corentin",
},
};
Object.seal(objectToSeal);
很簡(jiǎn)單吧?讓我們現(xiàn)在嘗試修改該對(duì)象:
delete objectToSeal.name;
objectToSeal.age = 56;
objectToSeal.lastName = "Cosset";
objectToSeal.sibling.age = 45;
objectToSeal.pets.push("Grenade");
也許你已經(jīng)猜到了應(yīng)該怎么辦
//objectToSeal new contents
{
name: 'Damien',
age: 56, //modifying worked
pets: ['Symba', 'Hades', 'Kiwi', 'Grenade'], // push worked
sibling: {
age: 45, // Modifying worked
name: 'Corentin'
}
}
// adding and deleting failed!
注意,就像Object.freeze一樣,Object.seal在非嚴(yán)格模式下將靜默失敗,并在嚴(yán)格模式下引發(fā)TypeError。
對(duì)象密封
我們還有一種方法可以知道對(duì)象是否被密封。非常明確地,我們可以調(diào)用Object.isSealed來(lái)知道:
Object.isSealed(objectToSeal); // === true
let notSealedObj = { a: 54 };
Object.isSealed(notSealedObj); // === false
const呢?
您可能會(huì)想看看Object.seal和Object.freeze并將它們與const進(jìn)行比較。請(qǐng)記住,它們是不同的概念。Object.freeze和Object.seal適用于對(duì)象的值,而const適用于binding。Object.freeze使對(duì)象不可變。const創(chuàng)建一個(gè)不可變的綁定。為變量分配值后,就無(wú)法為該綁定分配新值。
原型呢?
我最后要提的一件事是:原型。如果您不熟悉JAVAscript原型,我會(huì)寫(xiě)一篇文章。當(dāng)涉及到Object.freeze和Object.seal時(shí),要知道一旦凍結(jié)或密封它們后就不能更改它們的原型。
let freezeThat = {
name: 'Damien'
}
let sealThis = {
age 28
}
Object.freeze(freezeThat)
Object.seal(sealThis)
// These two lines will fail!
Object.setPrototypeOf(freezeThat, {x: 26})
Object.setPrototypeOf(sealThis, {alive: true})
setPrototypeOf用于更改對(duì)象的原型。將對(duì)象密封或凍結(jié)后,您將無(wú)法執(zhí)行此操作。與往常一樣,在非嚴(yán)格模式下,它將靜默失敗。在嚴(yán)格模式下,您會(huì)看到TypeError: Object is not extensible.
結(jié)論
了解Object.freeze和Object.seal之間的區(qū)別很重要。意識(shí)到這些差異將避免您在代碼中使用它們時(shí)遇到麻煩。
回顧一下: