← Назад к вопросам

Какие знаешь дескрипторы полей объекта?

1.7 Middle🔥 141 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Дескрипторы полей объекта — это объекты конфигурации, которые определяют, как свойства ведут себя в JavaScript. Они являются фундаментальной частью Property Descriptor API, доступного через методы Object.defineProperty(), Object.defineProperties() и Object.getOwnPropertyDescriptor().

Основные дескрипторы свойств

Каждый дескриптор может содержать следующие флаги:

1. Data Descriptors (дескрипторы данных)

Описывают свойства с конкретным значением:

const descriptor = {
  value: 'someValue',      // Значение свойства
  writable: true,          // Можно ли изменять значение
  enumerable: true,        // Будет ли свойство перечисляться в циклах
  configurable: true       // Можно ли удалять или изменять дескриптор
};

2. Accessor Descriptors (дескрипторы доступа)

Описывают свойства с геттерами и сеттерами:

const descriptor = {
  get() { return this._internal; },    // Функция-геттер
  set(val) { this._internal = val; },  // Функция-сеттер
  enumerable: true,
  configurable: true
};

Детальное описание каждого флага

value

Определяет значение свойства. Работает только с writable: true.

const obj = {};
Object.defineProperty(obj, 'name', {
  value: 'John',
  writable: false  // Теперь нельзя изменить obj.name
});

writable

Контролирует возможность изменения значения свойства. При false попытка присвоения в строгом режиме вызовет ошибку.

'use strict';
const obj = { x: 1 };
Object.defineProperty(obj, 'x', { writable: false });
obj.x = 2; // TypeError в строгом режиме

enumerable

Определяет, будет ли свойство появляться при:

  • Цикле for...in
  • Object.keys()
  • Object.values()
  • JSON.stringify()
  • Методе Object.assign()
const obj = { a: 1, b: 2 };
Object.defineProperty(obj, 'b', { enumerable: false });

console.log(Object.keys(obj)); // ['a']
for (let key in obj) {
  console.log(key); // только 'a'
}

configurable

Самый важный флаг, который контролирует:

  • Можно ли удалять свойство оператором delete
  • Можно ли изменять дескриптор (кроме перевода writable из true в false)
  • Можно ли изменять тип дескриптора (между data и accessor)
const obj = {};
Object.defineProperty(obj, 'x', {
  value: 1,
  configurable: false
});

// Нельзя удалить
delete obj.x; // false в нестрогом режиме

// Нельзя переопределить как accessor property
Object.defineProperty(obj, 'x', {
  get() { return 2; } // TypeError
});

get и set

Функции-аксессоры для создания вычисляемых свойств или свойств с валидацией:

const user = {
  _age: 25,
  
  get age() {
    return this._age;
  },
  
  set age(value) {
    if (value < 0) throw new Error('Invalid age');
    this._age = value;
  }
};

Практическое применение

1. Создание неизменяемых свойств

class Constants {
  constructor() {
    Object.defineProperty(this, 'PI', {
      value: 3.14159,
      writable: false,
      enumerable: true,
      configurable: false
    });
  }
}

2. Скрытие внутренних свойств

class SecureData {
  constructor(secret) {
    this._secret = secret;
    
    Object.defineProperty(this, 'secret', {
      get() {
        return this._secret.substring(0, 3) + '***';
      },
      enumerable: true
    });
  }
}

3. Оптимизация производительности

Свойства с enumerable: false не участвуют в сериализации, что может ускорить JSON.stringify() для больших объектов.

Особенности и ограничения

  1. Приоритеты: Если указаны и value/writable, и get/set, будет ошибка.
  2. Наследование: Дескрипторы не наследуются через прототипную цепочку.
  3. Значения по умолчанию: При создании свойства через присваивание все флаги получают значение true. При использовании Object.defineProperty() все флаги по умолчанию false.

Методы для работы с дескрипторами

// Получение дескриптора
const desc = Object.getOwnPropertyDescriptor(obj, 'property');

// Получение всех дескрипторов
const descriptors = Object.getOwnPropertyDescriptors(obj);

// Копирование свойств с дескрипторами
const copy = Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj)
);

Понимание дескрипторов полей объекта критически важно для:

  • Создания надежных API
  • Реализации инкапсуляции
  • Оптимизации производительности
  • Создания фреймворков и библиотек
  • Работы с Proxy и Reflection API

Дескрипторы лежат в основе многих современных возможностей JavaScript, включая приватные поля классов, реактивные системы и иммутабельные структуры данных.

Какие знаешь дескрипторы полей объекта? | PrepBro