Object.seal()
语法
seal<T>(o: T): T;
描述
该方法阻止给对象添加 新属性
,并将全部现有属性设为 不可配置
。
不可配置意味着 不能删除 已存在的属性,同时 不可将数据属性重新定义为访问器属性,也不可将访问器属性重新定义成为数据属性;
特殊地,如果一个属性的值是个 对象,则这个对象中的属性 不会被密封,除非也给它设置了 密封。
示例
const obj = {
firstName: 'Yancey',
lastName: 'Leo',
other: {
hobbies: ['girl'],
},
greeting() {
return `Hello, ${this.firstName}!`;
},
};
// 访问器属性
Object.defineProperty(obj, 'age', {
get() {
return 18;
},
});
Object.seal(obj);
Object.isExtensible(obj); // false
Object.isSealed(obj); // true
Object.isExtensible(obj); // false
新增属性和删除已有属性会失败,在严格模式下直接报错。
// 不能删除已有属性
delete obj.firstName; // false
// 不能新增属性
obj.newProperty = 'something...';
obj.newProperty; // undefined
// 严格模式下直接报错
function fail() {
'use strict';
// Uncaught TypeError: Cannot delete property 'firstName' of #<Object>
delete obj.firstName;
// Uncaught TypeError: Cannot add property newProperty, object is not extensible
obj.newProperty = 'something';
}
fail();
不可将数据属性重新定义成为访问器属性,同样也不可将访问器属性重新定义成为数据属性。
// TypeError: Cannot redefine property: lastName
Object.defineProperty(obj, 'lastName', {
get() {
return this.lastName;
},
});
// TypeError: Cannot redefine property: lastName
Object.defineProperty(obj, 'age', {
value: 18,
});
只要属性是可写的,那么它的值可以被修改。
obj.firstName = 'Sayaka';
obj.firstName; // 'Sayaka'
特殊地,如果一个属性的值是个 对象,则这个对象中的属性不会被密封,除非也给该属性设置了 密封。
// 可以成功删除
delete obj.other.hobbies; // true
obj.other.hobbies; // undefined
// 也可以新增
obj.other.newProperty = 'somthing';
obj.other.newProperty; // 'somthing'
不会影响从原型链上继承的属性,但 __proto__ 属性的值也会不能修改。
// TypeError: #<Object> is not extensible
obj.__proto__ = {
x: 20,
};
扩展
在 ES5 中,如果参数不是一个对象类型,将抛出一个 TypeError 异常。在 ES6+ 中,非对象参数将被视为已被密封的普通对象,因此会被直接返回。
// TypeError: 1 is not an object (ES5)
Object.seal(1);
// ES6+
Object.seal(1); // 1