myfreax

JavaScript 对象属性

在本教程中,您将了解 JavaScript 对象的数据属性和访问器属性,例如可配置、可枚举、可写、获取、设置和值

JavaScript 对象属性
JavaScript 对象属性

在本教程中,您将了解 JavaScript 对象的数据属性和访问器属性,例如可配置、可枚举、可写、获取、设置和值。

对象属性类型

JavaScript 通过两对方括号括起来的内部属性来指定对象的属性特征,例如[[Enumerable]] 等。对象有两种类型的属性:数据和访问器属性。

数据属性

数据属性包含数据值的单个位置。数据属性有四个属性:

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

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

以下示例创建一个 person 对象,person 对象有两个属性 firstNamelastName 并将可配置、可枚举和可写属性设置为 trueperson 对象的属性值分别设置为 'John''Doe'

let person = {
    firstName: 'John',
    lastName: 'Doe'
};

要修改对象属性的属性描述符,您可以使用 Object.defineProperty() 方法。Object.defineProperty() 方法接受三个参数:

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

在使用 Object.defineProperty() 方法定义对象的属性时,如果未指定四个属性描述符的值,Object.defineProperty() 方法将 [[Configurable]][[Enumerable]]、 和 [[Writable]] 的默认值设置为 false

以下示例创建一个具有 age 属性的 person 对象:

let person = {};
person.age = 25;

由于 [[Configurable]] 属性的默认值设置为 true,您可以通过 delete 运算符将属性删除:

delete person.age;
console.log(person.age);

输出:

undefined

以下示例创建一个 person 对象并使用 Object.defineProperty() 方法向其添加 ssn 属性:

'use strict';

let person = {};

Object.defineProperty(person, 'ssn', {
    configurable: false,
    value: '012-38-9119'
});

delete person.ssn;

输出:

TypeError: Cannot delete property 'ssn' of #<Object>

在此示例中,configurable 属性设置为 false。因此,删除 person 对象的 ssn 属性会导致错误, TypeError: Cannot delete property-类型错误不能删除属性。

此外,一旦将属性定义为不可配置,就无法再修改为可配置。如果您使用Object.defineProperty() 方法修改除可写属性之外的任何属性。

您将收到错误消息 TypeError: Cannot redefine property 。例如以下示例:

'use strict';

let person = {};

Object.defineProperty(person, 'ssn', {
    configurable: false,
    value: '012-38-9119'
});


Object.defineProperty(person, 'ssn', {
    configurable: true
});

输出:

TypeError: Cannot redefine property: ssn

默认情况下,一个对象定义的所有属性的 enumerable 属性都是 true。这意味着您可以使用  for...in 循环遍历所有对象属性:

let person = {};
person.age = 25;
person.ssn = '012-38-9119';

for (let property in person) {
    console.log(property);
}

输出:

age
ssn

以下示例将 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);
}

输出

age

访问器属性

与数据属性类似,访问器属性也有 [[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);

输出:

'John Doe'

在这个示例:

  • 首先,定义包含两个属性的 person 对象:firstNamelastName
  • 然后,将 fullName 属性作为访问器属性添加到 person 对象。

fullname 访问器属性中:

  • [[Get]] 返回 fullname, ,它是 firstNamespacelastName 连接的结果。
  • [[Set]] 方法按空格拆分参数,并将名称的相应部分分配给 firstNamelastName 属性。
  • 如果 fullname 的格式不正确,即名字、空格和姓氏,它将抛出错误

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');

输出:

The net price of a Smartphone is 878.90 USD

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

JavaScript 对象属性描述符

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

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

它返回描述属性的描述符对象。描述符对象有四个属性:可配置、可枚举、可写和值。下面的示例获取前面示例 product 对象的 name 属性的描述符对象。

let person = {
    firstName: 'John',
    lastName: 'Doe'
};


let descriptor = Object.getOwnPropertyDescriptor(person, 'firstName');

console.log(descriptor);

输出:

{ value: 'John',
  writable: true,
  enumerable: true,
  configurable: true }

结论

  • JavaScript 对象有两种类型的属性:数据属性和访问器属性。
  • JavaScript 使用 [[...]] 表示的内部属性来描述属性的特征,例如[[Configurable]][[Enumerable]][[Writable]]、 和  [[Value]][[Get]]、 和 [[Set]]
  • Object.getOwnPropertyDescriptor() 方法返回对象属性的属性描述符。
  • 属性可以直接在对象定义,也可以通过 Object.defineProperty()Object.defineProperties() 方法间接定义。这些方法可用于修改属性的特征。

内容导航