ES5 开始提供的,可与属性内部特征进行交互的 API
数据属性和访问器属性都具有的特征
[[Enumerable]]
决定是否可以遍历该属性[[Configurable]]
决定是否可配置,delete
操作符只可以删除可配置属性使用 Object.defineProperty()
方法来修改属性特征,属性接受3个参数
特征值对象中的 key, 使用
enumerable
来设置[[Enumerable]]
特征,使用configurable
来设置[[Configurable]]
特征,以此类推
const anObject = {
name: 'object',
};
Object.defineProperty(anObject, "name", {
enumerable: false,
});
console.log("name" in anObject); // true, anObject 是包含 name 属性
console.log(anObject.propertyIsEnumerable("name")); // false, 上面配置了 name 属性不可遍历
const properties = Object.keys(anObject);
console.log(properties.length); // 0, 由于上面配置了 name 属性不可遍历,因此 anObject 可遍历自有属性,没有!
Object.defineProperty(anObject, "name", {
configurable: false,
});
delete anObject.name;
console.log("name" in anObject); // true, 由于配置了 name 属性不可配置,因此 delete 并不起作用
// 严格模式下,抛出异常,配置属性变为不可配置,是一个单向操作
Object.defineProperty(anObject, "name", {
configurable: true,
});
[[Value]]
存放值的地方[[Writable]]
布尔类型,指示属性是否可写入使用 Object.defineProperty
方法,也可以为对象创建一个原本不存在的属性
const anObject = {};
Object.defineProperty(anObject, "name", {
value: 'object',
enumerable: true,
configurable: true,
writable: true,
});
使用 Object.defineProperty
为对象定义属性时,最好为所有特征值设置一个值,否则布尔型的特征,将会被设置为 false
, 会导致属性不可遍历,不可配置,不可写入
[[Get]]
即 getter[[Set]]
即 setter使用例子
const anObject = {
_name: 'object',
};
Object.defineProperty(anObject, 'name', {
get: function() {
// do something when reading value
return this._name;
},
set: function(value) {
// do something when setting value
this._name = value;
},
enumerable: true,
configurable: true,
});
同时对属性设置数据属性特征和访问器属性特征,将会报错 试图读取一个没有 getter 的属性,只会返回
undefined
Object.defineProperty
只能为对象定义一个属性,若需要为对象同时定义多个属性,则需要使用 Object.defineProperties
接受两个参数
const anObject = {};
Object.defineProperties(anObject, {
// 如果是定义数据属性
_name: {
value: 'object',
enumerable: true,
configurable: true,
writable: true,
},
// 如果是定义访问器属性
name: {
get: function() {
// do something when reading value
return this._name;
},
set: function(value) {
// do something when setting value
this._name = value;
},
},
});
使用 Object.getOwnPropertyDescriptor()
, 同时只能获取到自有属性,而返回的对象就是特征值,而特征值对象中的值,是根据属性是数据属性或访问器属性而定
const anObject = {
name: 'object',
};
const descriptor = Object.getOwnPropertyDescriptor(anObject, "name");
// descriptor.enumerable
// descriptor.configurable
// descriptor.writable
// descriptor.value