Типы свойств и атрибутов объектов в JavaScript

В этом руководстве вы узнаете о свойствах и атрибутах объекта JavaScript, таких как configurable, enumerable, writable, get, set и value.

JavaScript определяет характеристики свойств объектов с помощью внутренних атрибутов, заключенных в две пары квадратных скобок, например, [[Enumerable]].

Объекты имеют два типа свойств: данные и свойства доступа.

1) Свойства данных

Свойство данных содержит одно место для значения данных. Свойство данных имеет четыре атрибута:

  • [[Configurarable]] — определяет, может ли свойство быть переопределено или удалено с помощью оператора delete.
  • [[Enumerable]] — указывает, может ли свойство быть возвращено в цикле for...in.
  • [[Writable]] — указывает, что значение свойства может быть изменено.
  • [[Value]] — содержит фактическое значение свойства.

По умолчанию для атрибутов [[Configurable]], [[Enumerable]] и [[Writable]] установлено значение true для всех свойств, определенных непосредственно в объекте. Значение атрибута [[Value]] по умолчанию undefined.

В следующем примере создается объект person с двумя свойствами firstName и lastName с атрибутами configurable, enumerable и writable, для которых задано значение true. И их значения установлены на 'John' и 'Doe' соответственно:

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

Чтобы изменить любой атрибут свойства, вы используете метод Object.defineProperty().

Метод Object.defineProperty() принимает три аргумента:

  • Объект.
  • Имя свойства объекта.
  • Объект дескриптора свойства, который имеет четыре свойства: configurable, enumerable, writable и value.

Если вы используете метод Object.defineProperty() для определения свойства объекта, значения по умолчанию [[Configurable]], [[Enumerable]] и [[Writable]] устанавливаются равными false, если не указано иное.

В следующем примере создается объект person со свойством age :

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

Поскольку значение атрибута [[Configurable]] по умолчанию равно true, вы можете удалить его с помощью оператора delete :

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

Выход:

undefined

В следующем примере создается объект person и добавляется к нему свойство ssn с помощью Object.defineProperty() :

'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. поэтому удаление свойства ssn вызывает ошибку. Кроме того, если вы определили свойство как ненастраиваемое, вы не можете изменить его на настраиваемое. Если вы используете метод Object.defineProperty() для изменения любого атрибута, кроме доступного для записи, вы получите сообщение об ошибке. или пример:

'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. t означает, что вы можете перебирать все свойства объекта, используя цикл for...in следующим образом:

let person = {};
person.age = 25;
person.ssn = '012-38-9119';
for (let property in person) {
    console.log(property);
}

Выход:

age 
ssn

Следующее делает свойство ssn enumerable, присваивая атрибуту enumerable значение false.

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

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

Выход:

'John Doe'

В этом примере:

  • Сначала определите объект person, который содержит два свойства: firstName и lastName.
  • Затем добавьте свойство fullName в объект person в качестве свойства доступа.

В fullname доступа полного имени:

  • [[Get]] возвращает полное имя, которое является результатом объединения firstName, space и 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');

Выход:

The net price of a Smartphone is 878.90 USD

В этом примере мы определили три свойства данных: name, price и tax, а также одно свойство netPrice для объекта product.

Дескриптор свойства объекта

Метод Object.getOwnPropertyDescriptor() позволяет получить объект-дескриптор свойства. Метод Object.getOwnPropertyDescriptor() принимает два аргумента:

  1. Объект
  2. Свойство объекта

Он возвращает объект-дескриптор, описывающий свойство. Объект дескриптора имеет четыре свойства: configurable, enumerable, writable и value. Следующий пример получает объект дескриптора свойства name объекта product из предыдущего примера.

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(). Эти методы можно использовать для изменения атрибутов свойства.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript