JS 浅冻结与深冻结对象、解冻对象

什么是冻结?

JavaScript中对象的冻结指的是防止对象的属性被修改、删除或添加新属性。冻结对象又分为浅冻结与深冻结

对象的浅冻结

用法Object.freeze(obj)其中obj为要冻结的对象。

js 复制代码
const obj = { a: 1, b: { c: 2 } };
Object.freeze(obj);
obj.a = 2; 
obj.d = 4;
delete obj.b;
console.log(obj)

输出的值为:{ a: 1, b: { c: 2 } },被Object.freeze()冻结的对象无法进行对象属性的新增、修改跟删除。

判断一个对象是否被冻结可使用Object.isFreeze(obj),代码示例

js 复制代码
const obj = { a: 1, b: { c: 2 } };
Object.freeze(obj);
console.log(Object.isFrozen(obj))

输出结果为:true

如果属性的值是对象或者数组类型则会有另外情况,修改属性b的值,代码如下:

js 复制代码
const obj = { a: 1, b: { c: 2 } };
// shallowFreeze(obj);
Object.freeze(obj);
 
obj.a = 2; // 不起作用,保持原值1
obj.d = 4;
obj.b.c = 3; // 会起作用,但b对象不是冻结的,所以这会修改原对象
// delete obj.b;
console.log(obj)

输出结果为:{ a: 1, b: { c: 3 } },如果需要对属性b也实现冻结的话,就需要深冻结。

Object.seal()也用于防止 JavaScript 对象被修改。如果要防止添加新属性和删除现有属性,那么这两种方法都可以满足您的需要。但是,如果要防止现有属性被更改,则必须使用 Object.freeze()。原因就是 Object.seal() 只将现有 configurable 属性标记为不可配置,这意味着只要它们是可写的,就可以更改它们的值。

另外Object.isFrozen()不能监测到被Object.seal()处理的值,示例如下

js 复制代码
let obj = { a: 1, b: { c: 2 } };
Object.seal(obj)
obj.a = 2; 
obj.d = 4;
obj.b.c = 3; 
console.log(obj)
console.log(Object.isFrozen(obj))

输出:

{ a: 2, b: { c: 3 } }

false

对象的深冻结

深度冻结(deep freeze)策略指的是将对象及其所有嵌套对象的属性设置为只读并且不可修改的操作。这样做可以确保对象及其属性在冻结后不能被修改,以提高对象的不变性和安全性。

要实现深度冻结,可以使用Object.freeze()函数。这个函数会递归地冻结给定对象的属性,使其变为只读,并且不能添加、删除或修改属性。 示例如下:

js 复制代码
const deepFreeze = (obj) => {
    Object.freeze(obj);
    Object.getOwnPropertyNames(obj).forEach(prop => {
      if (typeof obj[prop] === 'object' && obj[prop] !== null) {
        deepFreeze(obj[prop]);
      }
    });
  };

const obj = { a: 1, b: { c: 2 } };
deepFreeze(obj);
 
obj.a = 2; // 不起作用,保持原值1
obj.d = 4;
obj.b.c = 3; 
console.log(obj)

输出结果:{ a: 1, b: { c: 2 } }

如何解冻

事实上, 在javascript中, 对象冻结后, 没有办法再解冻, 只能通过克隆一个具有相同属性的新对象, 通过修改新对象的属性来达到目的.

对象复制

js 复制代码
let obj = { a: 1, b: { c: 2 } };
Object.freeze(obj);
obj = JSON.parse(JSON.stringify(obj))
console.log(Object.isFrozen(obj))

输出值:false。

使用场景

  1. 防止对象被意外篡改,在开发过程中我们可能会配置一些固定不变的对象或者常量对象,这时候就需要使用到Object.freeze或者定义深冻结方法来确保不可变性,防止被意外修改
  2. 数据保护,我们需要传递一些数据给其他模块或者函数使用时,为了保证数据的完整性,可以使用对象冻结,防止被修改
  3. 提高性能,在某些情况下我们可以确定一个对象的属性不会再发生变化,可以使用冻结对象,让JavaScript的引擎在处理对象时更高效。
  4. 对象比较,在某些情况下,我们需要比较两个对象是否一致,如果都是冻结对象的话,可以通过简单的引用比较来判断它们是否相等,而不需要深度比较对象的属性。

总结

Object.freeze( ) 阻止Vue无法实现 响应式系统 当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生"响应",即匹配更新为新的值。但是如果使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

相关推荐
并不会35 分钟前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
悦涵仙子38 分钟前
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
javascript·css·sass
衣乌安、39 分钟前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜39 分钟前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师41 分钟前
CSS的三个重点
前端·css
耶啵奶膘2 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie4 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿5 小时前
webWorker基本用法
前端·javascript·vue.js