JavaScript 对象属性

摘要:在本教程中,您将了解 JavaScript 对象的属性和属性,例如可配置、可枚举、可写、get、set 和 value。

对象属性类型

JavaScript 通过用两对方括号包围的内部属性来指定 对象 属性的特征,例如 [[Enumerable]]

对象有两种类型的属性:数据属性和访问器属性。

1) 数据属性

数据属性包含一个用于数据值的单一位置。数据属性具有四个属性

  •  [[Configurarable]] – 确定是否可以通过 delete 运算符重新定义或删除属性。
  •  [[Enumerable]] – 指示属性是否可以在 for...in 循环中返回。
  •  [[Writable]] – 指定属性的值是否可以更改。
  •  [[Value]] – 包含属性的实际值。

默认情况下,[[Configurable]][[Enumerable]][[Writable]] 属性对于直接在对象上定义的所有属性都设置为 true[[Value]] 属性的默认值为 undefined

例如,以下代码创建了一个 person 对象,该对象具有两个属性 firstNamelastName,其可配置、可枚举和可写属性设置为 true,它们的值分别设置为 'John''Doe'

let person = {
    firstName: 'John',
    lastName: 'Doe'
};Code language: JavaScript (javascript)

要更改属性的任何属性,请使用 Object.defineProperty() 方法。

Object.defineProperty() 方法接受三个参数

  • 一个对象。
  • 对象的属性名称。
  • 一个属性描述符对象,该对象具有四个属性:configurableenumerablewritablevalue

如果您使用 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)

输出

undefinedCode 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: ssnCode 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 对象:firstNamelastName
  • 然后,将 fullName 属性添加为访问器属性到 person 对象。

fullname 访问器属性中

  • [[Get]] 返回全名,该全名是 firstName空格lastName串联 结果。
  • [[Set]] 方法 拆分 参数,并根据名称的相应部分分配 firstNamelastName 属性。
  • 如果全名格式不正确,即不符合姓、空格和姓的格式,它会 抛出错误

定义多个属性: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 USDCode language: CSS (css)

在此示例中,我们为 product 对象定义了三个数据属性:namepricetax,以及一个访问器属性 netPrice

JavaScript 对象属性描述符

Object.getOwnPropertyDescriptor() 方法允许您获取属性的描述符对象。Object.getOwnPropertyDescriptor() 方法接受两个参数

  1. 一个对象
  2. 对象的属性

它返回一个描述符对象,该对象描述一个属性。描述符对象具有四个属性: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() 方法间接定义。这些方法可用于更改属性的属性。
本教程是否有帮助?