属性标志和属性描述符
- 属性标志
writable
— 如果为true
,则值可以被修改,否则它是只可读的。enumerable
— 如果为true
,则会被在循环中列出,否则不会被列出。
configurable
— 如果为true
,则此属性可以被删除,这些特性也可以被修改,否则不可以。
- Object.getOwnPropertyDescriptor 方法允许查询有关属性的 完整 信息。
- let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
- obj:需要从中获取信息的对象。
- propertyName:属性的名称。
- let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
- 修改标志,我们可以使用 Object.defineProperty。
- Object.defineProperty(obj, propertyName, descriptor)
obj
,propertyName
:要应用描述符的对象及其属性。- descriptor:要应用的属性描述符对象。
- Object.defineProperty(obj, propertyName, descriptor)
- 只读
JavaScript
let user = {
name: "John"
};
Object.defineProperty(user, "name", {
writable: false
});
user.name = "Pete"; // Error: Cannot assign to read only property 'name'
1. 只在严格模式下会出现 Errors
- 不可枚举
- 对象中内建的
toString
是不可枚举的,它不会显示在for..in
中。
- 对象中内建的
- 不可配置
- 不可配置标志(
configurable:false
)有时会预设在内建对象和属性中。 - 请注意:
configurable: false
防止更改和删除属性标志,但是允许更改对象的值。
- 不可配置标志(
- 唯一可行的特性更改:writable true → false
- Object.defineProperties
- 有一个方法 Object.defineProperties(obj, descriptors),允许一次定义多个属性。
- Object.getOwnPropertyDescriptors
- 要一次获取所有属性描述符,我们可以使用 Object.getOwnPropertyDescriptors(obj) 方法。
- 设定一个全局的密封对象
- Object.preventExtensions(obj):禁止向对象添加新属性。
- Object.seal(obj):禁止添加/删除属性。为所有现有的属性设置
configurable: false
。 - Object.freeze(obj):禁止添加/删除/更改属性。为所有现有的属性设置
configurable: false, writable: false
。 - Object.isExtensible(obj):如果添加属性被禁止,则返回
false
,否则返回true
。 - Object.isSealed(obj):如果添加/删除属性被禁止,并且所有现有的属性都具有
configurable: false
则返回true
。 - Object.isFrozen(obj):如果添加/删除/更改属性被禁止,并且所有当前属性都是
configurable: false, writable: false
,则返回true
。
属性的 getter 和 setter
第一种是 数据属性。我们已经知道如何使用它们了。到目前为止,我们使用过的所有属性都是数据属性。 第二种类型的属性是新东西。它是 访问器属性(accessor property)。它们本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。
- getter 和 setter
JavaScript
let obj = {
get propName() {
// 当读取 obj.propName 时,getter 起作用
},
set propName(value) {
// 当执行 obj.propName = value 操作时,setter 起作用
}
};
- 访问器描述符 -
get
—— 一个没有参数的函数,在读取属性时工作,set
—— 带有一个参数的函数,当属性被设置时调用,enumerable
—— 与数据属性的相同,configurable
—— 与数据属性的相同。
- 更聪明的 getter/setter
- getter/setter 可以用作“真实”属性值的包装器,以便对它们进行更多的控制。
JavaScript
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("Name is too short, need at least 4 characters");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // Name 太短了……
- 兼容性
- 访问器的一大用途是,它们允许随时通过使用 getter 和 setter 替换“正常的”数据属性,来控制和调整这些属性的行为。