一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法


一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法

文章插图
 
对象冻结这是使用Object.freeze的方法:
let objectToFreeze = {age: 28,name: "Damien",pets: ["Symba", "Hades", "Kiwi"],sibling: {age: 25,name: "Corentin",},};Object.freeze(objectToFreeze);Object.freeze将对象作为参数 。请注意 , 它修改了您作为参数传递的对象 。它不会复制对象并创建一个新对象 。
那么这对物体意味着什么呢?
  • 您不能向对象添加新属性
  • 如果属性本身不是对象或数组 , 则无法修改 。(稍后会详细介绍)
  • 您不能从对象中删除属性
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";根据我刚才给您的描述 , 您应该猜测该对象现在的外观:
console.log(objectToFreeze)// objectToFreeze :{ age: 28,name: 'Damien',pets: [ 'Symba', 'Hades', 'Kiwi', 'Grenade' ],sibling: {age: 25,name: 'Corentin'}}该删除失败 , 修改名称属性失败并添加lastName的失败财产 。但是修改数组是可行的 。
注意:如果您不在严格模式下 , 它将以静默方式失败 。在严格模式下 , 您将收到TypeErrors
"use strict";let objectToFreeze = {age: 28,name: "Damien",pets: ["Symba", "Hades", "Kiwi"],sibling: {age: 25,name: "Corentin",},};Object.freeze(objectToFreeze);delete objectToFreeze.age;抛出这个:
一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法

文章插图
 
浅冻结当我们称为Object.freeze时 , 我们所拥有的只是一个浅冻结 。我们仅冻结直接附加到对象的对象 。不关心对象和数组内部的属性 。
为了使整个对象以及其中的所有内容不可变 , 您必须在每个元素上调用Object.freeze() 。这是您可以执行此操作的一种方法:
let allYouCanFreeze = () => {// Retrieve the properties nameslet 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 = https://www.isolves.com/it/cxkf/yy/js/2020-06-05/obj[name];obj[name] =value && typeof value === "object" ? allYouCanFreeze(value) : value;}// Finally, freeze the main objectreturn Object.freeze(obj);};让我们在第一个对象上使用它:
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 objectobjectToFreeze.age = 26; // Now, fails.objectToFreeze.pets.push("Grenade"); // Now, fails大!现在 , 我们的兄弟对象和pets数组无法修改 。
对象冻结要知道对象是否被冻结 , 可以使用Object.isFrozen():
【一文彻底搞懂JavaScript 中Object.freeze与Object.seal的用法】Object.isFrozen(objectToFreeze); // === truelet unfrozenObj = { a: 42 };Object.isFrozen(unfrozenObj); // === false物体密封像Frozen方法一样 , Object.seal()也将对象作为参数 。Object.seal是Object.freeze的较软版本 。
  • 您不能删除或向对象添加元素 。
  • 您可以修改现有属性 。
let objectToSeal = {name: "Damien",age: 28,pets: ["Symba", "Hades", "Kiwi"],sibling: {age: 25,name: "Corentin",},};Object.seal(objectToSeal);很简单吧?让我们现在尝试修改该对象:
delete objectToSeal.name;objectToSeal.age = 56;objectToSeal.lastName = "Cosset";objectToSeal.sibling.age = 45;objectToSeal.pets.push("Grenade");也许你已经猜到了应该怎么办
//objectToSeal new contents{name: 'Damien',age: 56, //modifying workedpets: ['Symba', 'Hades', 'Kiwi', 'Grenade'], // push workedsibling: {age: 45, // Modifying workedname: 'Corentin'}}// adding and deleting failed!注意 , 就像Object.freeze一样 , Object.seal在非严格模式下将静默失败 , 并在严格模式下引发TypeError 。


推荐阅读