# 题目描述

请你实现Object.freeze函数的功能且该新函数命名为"_objectFreeze"

# 测试用例

function test() {
  const o = { name: "z", fn: function () {} };
  _objectFreeze(o);
  o.name = "g";
  o.fn = 1;
  o.o = 1;
  const result =
    o.name === "z" && typeof o.fn === "function" && o.o === undefined;
  return result;
}
1
2
3
4
5
6
7
8
9
10

# 分析

  • 不可枚举的属性也要冻结 —— 使用Object.getOwnPropertyNames()
  • Symbol类型的属性要冻结 —— Object.getOwnPropertySymbols()
  • 不冻结原型链的属性 —— forEach 不能使用for...in
  • 冻结对象的可扩展性 —— Object.preventExtensionsObject.seal()
  • Object.freezeshallow freeze —— 所以只要冻结对象的一层属性
  • 冻结实现 —— 配置对象属性的writableconfigurablefalse

# 代码实现

const _objectFreeze = (object) => {
  // 补全代码
  if (typeof object != "object" || object == null) {
    throw new TypeError(`the ${object} is not a object`);
  }
  const keys = Object.getOwnPropertyNames(object);
  const symbols = Object.getOwnPropertySymbols(object);

  // 把object所有的属性包括symbol设置configurable和writable为false
  [...keys, ...symbols].forEach((item) => {
    Object.defineProperty(object, item, {
      configurable: false,
      writable: false,
    });
  });

  // 设置不可扩展
  Object.seal(object);
};

function test() {
  const o = { name: "z", fn: function () {} };
  _objectFreeze(o);
  o.name = "g";
  o.fn = 1;
  o.o = 1;
  const result =
    o.name === "z" && typeof o.fn === "function" && o.o === undefined;
  return result;
}

console.log(test());
// true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33