摘要:在本教程中,您将了解 JavaScript 对象的属性和属性,例如可配置、可枚举、可写、get、set 和 value。
对象属性类型
JavaScript 通过用两对方括号包围的内部属性来指定 对象 属性的特征,例如 [[Enumerable]]
。
对象有两种类型的属性:数据属性和访问器属性。
1) 数据属性
数据属性包含一个用于数据值的单一位置。数据属性具有四个属性
-
[[Configurarable]]
– 确定是否可以通过delete
运算符重新定义或删除属性。 -
[[Enumerable]]
– 指示属性是否可以在for...in
循环中返回。 -
[[Writable]]
– 指定属性的值是否可以更改。 -
[[Value]]
– 包含属性的实际值。
默认情况下,[[Configurable]]
、[[Enumerable]]
和 [[Writable]]
属性对于直接在对象上定义的所有属性都设置为 true
。[[Value]]
属性的默认值为 undefined
。
例如,以下代码创建了一个 person
对象,该对象具有两个属性 firstName
和 lastName
,其可配置、可枚举和可写属性设置为 true
,它们的值分别设置为 'John'
和 'Doe'
let person = {
firstName: 'John',
lastName: 'Doe'
};
Code language: JavaScript (javascript)
要更改属性的任何属性,请使用 Object.defineProperty()
方法。
Object.defineProperty()
方法接受三个参数
- 一个对象。
- 对象的属性名称。
- 一个属性描述符对象,该对象具有四个属性:
configurable
、enumerable
、writable
和value
。
如果您使用 Object.defineProperty()
方法来定义对象的属性,则 [[Configurable]]
、[[Enumerable]]
和 [[Writable]]
的默认值将设置为 false
,除非另有指定。
以下示例创建一个 person
对象,并使用 Object.defineProperty()
方法向其添加 age
属性
let person = {};
person.age = 25;
Code language: JavaScript (javascript)
由于 [[Configurable]]
属性的默认值设置为 true
,因此您可以通过 delete
运算符将其删除
delete person.age;
console.log(person.age);
Code language: CSS (css)
输出
undefined
Code language: JavaScript (javascript)
以下示例创建一个 person
对象,并使用 Object.defineProperty()
方法向其添加 ssn
属性
'use strict';
let person = {};
Object.defineProperty(person, 'ssn', {
configurable: false,
value: '012-38-9119'
});
delete person.ssn;
Code language: JavaScript (javascript)
输出
TypeError: Cannot delete property 'ssn' of #<Object>
Code language: PHP (php)
在此示例中,configurable
属性设置为 false
。因此,删除 ssn
属性会导致错误。
此外,一旦您将属性定义为不可配置的,就不能将其更改为可配置的。
如果您使用 Object.defineProperty()
方法来更改除可写属性之外的任何属性,您将收到错误。例如
'use strict';
let person = {};
Object.defineProperty(person, 'ssn', {
configurable: false,
value: '012-38-9119'
});
Object.defineProperty(person, 'ssn', {
configurable: true
});
Code language: JavaScript (javascript)
输出
TypeError: Cannot redefine property: ssn
Code language: JavaScript (javascript)
默认情况下,对象上定义的所有属性的 enumerable
属性为 true
。这意味着您可以使用 for...in
循环遍历所有对象属性,如下所示
let person = {};
person.age = 25;
person.ssn = '012-38-9119';
for (let property in person) {
console.log(property);
}
Code language: JavaScript (javascript)
输出
age
ssn
以下代码通过将 enumerable
属性设置为 false
来使 ssn
属性不可枚举。
let person = {};
person.age = 25;
person.ssn = '012-38-9119';
Object.defineProperty(person, 'ssn', {
enumerable: false
});
for (let prop in person) {
console.log(prop);
}
Code language: JavaScript (javascript)
输出
age
2) 访问器属性
与数据属性类似,访问器属性也具有 [[Configurable]]
和 [[Enumerable]]
属性。
但访问器属性具有 [[Get]]
和 [[Set]]
属性,而不是 [[Value]]
和 [[Writable]]
。
当您从访问器属性中读取数据时,会自动调用 [[Get]]
函数以返回一个值。[[Get]]
函数的默认返回值为 undefined
。
如果您为访问器属性分配一个值,则会自动调用 [[Set]]
函数。
要定义访问器属性,必须使用 Object.defineProperty()
方法。例如
let person = {
firstName: 'John',
lastName: 'Doe'
}
Object.defineProperty(person, 'fullName', {
get: function () {
return this.firstName + ' ' + this.lastName;
},
set: function (value) {
let parts = value.split(' ');
if (parts.length == 2) {
this.firstName = parts[0];
this.lastName = parts[1];
} else {
throw 'Invalid name format';
}
}
});
console.log(person.fullName);
Code language: JavaScript (javascript)
输出
'John Doe'
Code language: JavaScript (javascript)
在此示例中
- 首先,定义包含两个属性的
person
对象:firstName
和lastName
。 - 然后,将
fullName
属性添加为访问器属性到person
对象。
在 fullname
访问器属性中
[[Get]]
返回全名,该全名是firstName
、空格
和lastName
的 串联 结果。[[Set]]
方法 拆分 参数,并根据名称的相应部分分配firstName
和lastName
属性。- 如果全名格式不正确,即不符合姓、空格和姓的格式,它会 抛出错误。
定义多个属性:Object.defineProperties()
在 ES5 中,可以使用 Object.defineProperties()
方法在单个语句中定义多个属性。例如
var product = {};
Object.defineProperties(product, {
name: {
value: 'Smartphone'
},
price: {
value: 799
},
tax: {
value: 0.1
},
netPrice: {
get: function () {
return this.price * (1 + this.tax);
}
}
});
console.log('The net price of a ' + product.name + ' is ' + product.netPrice.toFixed(2) + ' USD');
Code language: JavaScript (javascript)
输出
The net price of a Smartphone is 878.90 USD
Code language: CSS (css)
在此示例中,我们为 product
对象定义了三个数据属性:name
、price
和 tax
,以及一个访问器属性 netPrice
。
JavaScript 对象属性描述符
Object.getOwnPropertyDescriptor()
方法允许您获取属性的描述符对象。Object.getOwnPropertyDescriptor()
方法接受两个参数
- 一个对象
- 对象的属性
它返回一个描述符对象,该对象描述一个属性。描述符对象具有四个属性:configurable、enumerable、writable 和 value。
以下示例获取先前示例中 product
对象的 name
属性的描述符对象。
let person = {
firstName: 'John',
lastName: 'Doe'
};
let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');
console.log(descriptor);
Code language: JavaScript (javascript)
输出
{ value: 'John',
writable: true,
enumerable: true,
configurable: true }
Code language: CSS (css)
总结
- JavaScript 对象具有两种类型的属性:数据属性和访问器属性。
- JavaScript 使用表示为
[[...]]
的内部属性来描述属性的特征,例如[[Configurable]]
、[[Enumerable]]
、[[Writable]]
和[[Value]]
、[[Get]]
和[[Set]]
。 Object.getOwnPropertyDescriptor()
方法返回对象中属性的属性描述符。- 属性可以直接在对象上定义,也可以通过
Object.defineProperty()
或Object.defineProperties()
方法间接定义。这些方法可用于更改属性的属性。