Object.seal()

Object.seal() 静态方法密封一个对象。密封一个对象阻止扩展并使现有属性不可配置。密封的对象具有固定的属性集:无法添加新属性、无法删除现有属性、无法更改其可枚举性和可配置性,以及无法重新分配其原型。只要可写,现有属性的值仍然可以更改。seal() 返回与传入的相同对象。

尝试一下

语法

js
Object.seal(obj)

参数

obj

要密封的对象。

返回值

被密封的对象。

描述

密封一个对象等效于阻止扩展,然后将所有现有属性的描述符更改为configurable: false。这将使对象的属性集固定。使所有属性不可配置还会阻止它们从数据属性转换为访问器属性,反之亦然,但不会阻止数据属性的值更改。尝试删除或添加密封对象的属性,或将数据属性转换为访问器属性或反之,将失败,要么静默失败,要么抛出一个TypeError(最常见,但并非唯一,是在严格模式代码中)。

私有属性没有属性描述符的概念。无论对象是否已密封,都无法从对象中添加或删除私有属性。

原型链保持不变。但是,由于阻止扩展的影响,[[Prototype]] 无法重新分配。

Object.freeze() 不同,使用 Object.seal() 密封的对象可以更改其现有属性,只要这些属性是可写的。

示例

使用 Object.seal

js
const obj = {
  prop() {},
  foo: "bar",
};

// New properties may be added, existing properties
// may be changed or removed.
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

const o = Object.seal(obj);

o === obj; // true
Object.isSealed(obj); // true

// Changing property values on a sealed object
// still works.
obj.foo = "quux";

// But you can't convert data properties to accessors,
// or vice versa.
Object.defineProperty(obj, "foo", {
  get() {
    return "g";
  },
}); // throws a TypeError

// Now any changes, other than to property values,
// will fail.
obj.quaxxor = "the friendly duck";
// silently doesn't add the property
delete obj.foo;
// silently doesn't delete the property

// ...and in strict mode such attempts
// will throw TypeErrors.
function fail() {
  "use strict";
  delete obj.foo; // throws a TypeError
  obj.sparky = "arf"; // throws a TypeError
}
fail();

// Attempted additions through
// Object.defineProperty will also throw.
Object.defineProperty(obj, "ohai", {
  value: 17,
}); // throws a TypeError
Object.defineProperty(obj, "foo", {
  value: "eit",
}); // changes existing property value

非对象参数

在 ES5 中,如果此方法的参数不是对象(原始类型),则会引发TypeError。在 ES2015 中,非对象参数将按原样返回,不会引发任何错误,因为原始类型本身就是不可变的。

js
Object.seal(1);
// TypeError: 1 is not an object (ES5 code)

Object.seal(1);
// 1                             (ES2015 code)

规范

规范
ECMAScript 语言规范
# sec-object.seal

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅