如何在javascript中冻结嵌套对象?

mad*_*ox2 5 javascript

我偶然发现了Object.freeze()函数.它似乎是一个非常好的功能,但如何使整个对象(包括嵌套对象)不可变?

例如我可以innerProp在这里改变:

const obj = { prop: { innerProp: 1 } };
obj.prop.innerProp = 5;
console.log(obj.prop.innerProp); // 5
Run Code Online (Sandbox Code Playgroud)

是否有可能冻结嵌套对象?(ECMAScript 5/6)

bir*_*day 12

function deepFreeze (o) {
  Object.freeze(o);
  if (o === undefined) {
    return o;
  }

  Object.getOwnPropertyNames(o).forEach(function (prop) {
    if (o[prop] !== null
    && (typeof o[prop] === "object" || typeof o[prop] === "function")
    && !Object.isFrozen(o[prop])) {
      deepFreeze(o[prop]);
    }
  });

  return o;
};
Run Code Online (Sandbox Code Playgroud)

https://github.com/substack/deep-freeze

这是公共领域,所以你不必给予信任:D

  • deepFreeze fn 很糟糕。为什么在传递给 `Object.freeze` 后检查 o 是否未定义?为什么不使用“o == null”而不是“o === undefined”,因为这样对于“null”和“undefined”来说,条件将为“true” (2认同)

rah*_*hul 5

在 TS 和 ES2015 中该函数可以变得更加简洁。

import type { ReadonlyDeep } from 'type-fest';

export function deepFreeze<T>(o: T) {
  Object.values(o).forEach(v => Object.isFrozen(v) || deepFreeze(v));
  return Object.freeze(o) as ReadonlyDeep<T>;
}
Run Code Online (Sandbox Code Playgroud)
  • Object.isFrozen 现在对于原始对象返回 true。
  • Object.values 而不是 getOwnPropertyNames。