Advertisement

【JavaScript】Object.freeze是什么?

阅读量:

JavaScript中的一个冻结函数Object.freeze被用来阻止对对象进行任何修改操作。它所作用的对象具备以下特性包括:保持属性值不变、不可变型以及无法被重新定义或删除属性。

  1. 不允许新增任何新的字段或属性。
  2. 现有字段或属性不得被删除。
  3. 现有字段或属性的状态不得更改。
  4. 现有字段或属性的配置不得修改(例如writable、configurable和enumerable等参数)。

用途

Object.freeze 主要用在以下场景:

  • 防止数据发生非预期更改
  • 创建Immutable Data Structures
  • 增加性能通过利用Immutable对象的特性进行优化

如何使用 Object.freeze

冻结对象

你可以使用 Object.freeze 方法来冻结一个对象:

复制代码
    const obj = {
      name: 'Alice',
      age: 25,
    };
    
    const frozenObj = Object.freeze(obj);
    
    
      
      
      
      
      
      
    
    代码解读
冻结后的效果

在对象被锁定之后, 不能再对其实施任何更改操作. 以下列举了几个针对冻结对象的修改尝试:

添加新属性

复制代码
    frozenObj.newProp = 'value'; // 不生效,frozenObj 新增属性无效

    
    
         
    代码解读

删除现有属性

复制代码
    delete frozenObj.age; // 不生效,age 属性仍然存在

    
    
         
    代码解读

修改现有属性的值

复制代码
    frozenObj.name = 'Bob'; // 不生效,name 的值仍然是 'Alice'

    
    
         
    代码解读

修改现有属性的配置

复制代码
    Object.defineProperty(frozenObj, 'age', { writable: false }); // 不生效

    
    
         
    代码解读

示例代码

创建并冻结对象
复制代码
    const person = {
      name: 'Alice',
      age: 25,
    };
    
    const frozenPerson = Object.freeze(person);
    
    console.log(frozenPerson); // 输出 "{ name: 'Alice', age: 25 }"
    
    
      
      
      
      
      
      
      
      
    
    代码解读
尝试修改冻结后的对象
复制代码
    frozenPerson.name = 'Bob'; // 不生效
    delete frozenPerson.age; // 不生效
    
    console.log(frozenPerson); // 输出 "{ name: 'Alice', age: 25 }"
    
    
      
      
      
      
    
    代码解读

检查是否冻结

你可以使用 Object.isFrozen 方法检查一个对象是否已经被冻结。

检查冻结状态
复制代码
    function isFrozen(obj) {
      if (!Object.isFrozen) {
    throw new Error('当前环境不支持 Object.isFrozen 方法');
      }
    
      return Object.isFrozen(obj);
    }
    
    console.log(isFrozen(frozenPerson)); // 输出 true
    console.log(isFrozen(person));       // 输出 false (未冻结)
    
    
      
      
      
      
      
      
      
      
      
      
    
    代码解读

注意事项

表面冻结(peel-freezing)是一种技术Object.freeze 仅限于固定其顶层属性,并无法应用于复杂的对象结构或多维数组。

深拷贝冻结 :若需要彻底冻结一个大分子对象,则可采用深拷贝后再进行冻结。

浅层冻结 vs 深层冻结
复制代码
    const nestedObj = {
      name: 'Alice',
      details: {
    age: 25,
    city: 'New York'
      }
    };
    
    const frozenNestedObj = Object.freeze(nestedObj);
    
    nestedObj.details.age = 30; // 修改成功!因为 details 是一个对象
    
    console.log(nestedObj); // 输出 "{ name: 'Alice', details: { age: 30, city: 'New York' } }"
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
深拷贝冻结
复制代码
    const deepFreeze = (obj) => {
      for (let key in obj) {
    if (typeof obj[key] === 'object' && obj[key] !== null) {
      deepFreeze(obj[key]);
    }
      }
      
      return Object.freeze(obj);
    };
    
    const deepFrozenNestedObj = deepFreeze(nestedObj);
    
    deepFrozenNestedObj.details.age = 30; // 不生效!
    
    console.log(deepFrozenNestedObj); // 输出 "{ name: 'Alice', details: { age: 25, city: 'New York' } }"
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

总结

Object.freeze 是一种有力的工具,在多种情况下防止意外修改。特别适用于那些要求数据保持不变的情况。

全部评论 (0)

还没有任何评论哟~