preventExtensions & seal & freez

216 阅读2分钟

preventExtensions

使得一个对象变的不可扩展。可以新增、删除属性

let obj = {
  name: "ngnice",
  age: 10,
  utils: {
    log() {}
  }
};
console.log("isExtensible: ", Object.isExtensible(obj));
Object.preventExtensions(obj);
console.log("isExtensible: ", Object.isExtensible(obj));
// 在严格模式下会报错 非严格模式下 不生效
obj.alo = "12121";
console.log("尝试访问新添加的属性:", obj.alo);
// 删除已经存在的属性
delete obj.name;
console.log("删除之后 访问", obj.name);
// 对象内部的引用类型不受影响
obj.utils.newlog = function () {
  console.log("new log");
};
obj.utils.newlog();
console.log("obj.utils 是否可以扩展:", Object.isExtensible(obj.utils));
// 可以将obj指向新的对象来 让preventExtension失效
// 原因是指向了不同的引用对象
obj = {};
obj.aaa = "new prop";
console.log(obj.aaa);

总结:

  1. 不可以新增属性;严格模式下 尝试给禁止扩展的对象添加属性,会报错;非严格模式下 不会
  2. 可以删除已经存在的key
  3. 对象下的属性如果是引用类型,对应的属性值还是可以扩展的
  4. 可以通过将对象变量指向新的引用,来达到绕过禁止扩展的效果

Object.seal

let obj = {
  name: "ngnice",
  age: 10,
  utils: {}
};

Object.seal(obj);

// 尝试删除已经存在的属性
// 失败,严格模式下 会报错
delete obj.name;
console.log(obj.name);

// 尝试新增属性
obj.log = function () {};
console.log(obj.log);
// 修改引用类型的属性值
obj.utils.log = function () {
  console.log("utils log method");
};
obj.utils.log();
// 更改原型对象 报错
Object.setPrototypeOf(obj, {});
console.log("obj.__proto__", obj.__proto__);
// 指向新的引用 绕过
obj = {};
obj.log = function () {
  console.log("I' am new obj");
};
obj.log();

总结:

  1. 不可以新增属性;严格模式下 尝试给禁止扩展的对象添加属性,会报错;非严格模式下 不会
  2. 不可以删除
  3. 对象下的属性如果是引用类型,对应的属性值还是可以扩展的
  4. 可以通过将对象变量指向新的引用,来达到绕过禁止扩展的效果
  5. 原型对象不可以更改

Object.freeze

  1. 不可以新增
  2. 不可以删除
  3. 不可以修改属性配置
  4. 对象下的属性如果是引用类型,对应的属性值还是可以扩展的
  5. 可以通过将对象变量指向新的引用,来达到绕过禁止扩展的效果
  6. 原型对象不可以更改