Movatterモバイル変換


[0]ホーム

URL:


  1. Веб-технологии для разработчиков
  2. JavaScript
  3. Справочник по JavaScript
  4. Стандартные встроенные объекты
  5. Object
  6. Object.defineProperty()

This page was translated from English by the community.Learn more and join the MDN Web Docs community.

View in EnglishAlways switch to English

Object.defineProperty()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨июль 2015 г.⁩.

Сводка

Статический методObject.defineProperty() определяет новое или изменяет существующее свойство объекта и возвращает этот объект.

Интерактивный пример

const object1 = {};Object.defineProperty(object1, "property1", {  value: 42,  writable: false,});object1.property1 = 77;// Throws an error in strict modeconsole.log(object1.property1);// Expected output: 42

Синтаксис

js
Object.defineProperty(obj, prop, descriptor)

Параметры

obj

Объект, на котором определяется свойство.

prop

Строка илиSymbol с ключом определяемого или изменяемого свойства.

descriptor

Дескриптор определяемого или изменяемого свойства.

Описание

Этот метод позволяет точно добавлять или изменять свойства объекта. Обычное добавление свойств через присваивание создаёт свойства, которые можно увидеть через перечисление свойств (с помощью циклаfor...in или методаObject.keys), чьи значения могут быть изменены и которые могут бытьудалены. Этот же метод позволяет настроить эти дополнительные детали свойства.

Дескрипторы свойств, присутствующие в объектах, бывают двух основных типов: дескрипторы данных и дескрипторы доступа.Дескриптор данных — это свойство, имеющее значение, которое может быть (а может и не быть) записываемым.Дескриптор доступа — это свойство, описываемое парой функций — геттером и сеттером. Дескриптор может быть только чем-то одним из этих двух типов; он не может быть одновременно обоими.

И дескриптор данных, и дескриптор доступа являются объектами. Они обладают следующими обязательными ключами:

configurable

Равенtrue только в том случае, если тип этого дескриптора свойства может быть изменён и если свойство может быть удалено из содержащего его объекта.Значение по умолчанию установлено вfalse.

enumerable

Равенtrue только в том случае, если это свойство можно увидеть через перечисление свойств содержащего его объекта.Значение по умолчанию установлено вfalse.

Дескриптор данных также может содержать следующие дополнительные ключи:

value

Значение, ассоциированное со свойством. Может быть любым допустимым значением JavaScript (числом, объектом, функцией и т.д.).Значение по умолчанию установлено вundefined.

writable

Равенtrue только в том случае, если значение, ассоциированное со свойством, может быть изменено с помощьюоператора присваивания.Значение по умолчанию установлено вfalse.

Дескриптор доступа также может содержать следующие дополнительные ключи:

get

Функция, используемая как геттер свойства, либоundefined, если свойство не имеет геттера. Возвращаемое значение функции будет использоваться как значение свойства.Значение по умолчанию установлено вundefined.

set

Функция, используемая как сеттер свойства, либоundefined, если свойство не имеет сеттера. Функция принимает единственным аргументом новое значение, присваиваемое свойству.Значение по умолчанию установлено вundefined.

Имейте в виду, что эти ключи не обязательно должны принадлежать самому дескриптору свойства, если они унаследованы, они так же будут приниматься во внимание. Для сохранения этих ключей по умолчанию неизменными, вы можете заранее заморозитьObject.prototype, явно определив все ключи, либо установить свойствоObject.prototype.__proto__ вnull.

js
// Использование __proto__Object.defineProperty(obj, "key", {  __proto__: null, // нет унаследованных свойств  value: "static", // по умолчанию  // не перечисляется,  // не настраивается и  // не перезаписывается});// Явное определение свойстваObject.defineProperty(obj, "key", {  enumerable: false,  configurable: false,  writable: false,  value: "static",});// Переиспользование одного и того же объектаfunction withValue(value) {  var d =    withValue.d ||    (withValue.d = {      enumerable: false,      writable: false,      configurable: false,      value: null,    });  d.value = value;  return d;}// ... и ...Object.defineProperty(obj, "key", withValue("static"));// Если доступен метод freeze, предотвращаем добавление свойств// value, get, set, enumerable, writable и configurable// к прототипу Object(Object.freeze || Object)(Object.prototype);

Примеры

Пример: создание свойства

Если указанное свойство не существует в объекте, методObject.defineProperty() создаст новое свойство по переданному описанию. Поля в дескрипторе могут быть опущены, в этом случае их значения будут значениями по умолчанию. Все логические поля будут по умолчанию установлены вfalse. Поляvalue,get иset по умолчанию будут установлены вundefined. Свойство, определённое без атрибутовget/set/value/writable называется «общим», а дескриптор данных — «типовым».

js
var o = {}; // Создаём новый объект// Пример добавления свойства к объекту через defineProperty()// с дескриптором данныхObject.defineProperty(o, "a", {  value: 37,  writable: true,  enumerable: true,  configurable: true,});// Свойство 'a' существует в объекте o и имеет значение, равное 37// Пример добавления свойства к объекту через defineProperty()// с дескриптором доступаvar bValue = 38;Object.defineProperty(o, "b", {  get: function () {    return bValue;  },  set: function (newValue) {    bValue = newValue;  },  enumerable: true,  configurable: true,});o.b; // 38// Свойство 'b' существует в объекте o и имеет значение, равное 38// Значение свойства o.b теперь идентично значению bValue до тех пор,// пока свойство o.b не будет переопределено// Вы не можете смешать два этих подхода:Object.defineProperty(o, "conflict", {  value: 0x9f91102,  get: function () {    return 0xdeadbeef;  },});// Выкинет исключение TypeError: свойство value применимо только в// дескрипторах данных, свойство get применимо только в дескрипторах// доступа

Пример: изменение свойства

Если свойство уже существует, методObject.defineProperty() попытается изменить свойство в соответствии со значениями в дескрипторе и текущим состоянием объекта.

Если у старого дескриптора атрибутconfigurable был установлен вfalse, то свойство являетсяненастраиваемым. Нельзя изменять атрибуты ненастраиваемых свойств, а также нельзя изменять тип дескриптора. Для свойств данных сwritable: true можно изменять значение и изменять атрибутwritable сtrue наfalse. При попытке изменить ненастраиваемые атрибуты свойств возникает ошибкаTypeError. Исключения составляют атрибутыvalue иwritable (если это разрешено) и если новое значение совпадает с исходным значением свойства данных.

Если свойство является настраиваемым, то установка атрибуту значенияundefined равно его удалению. Например, еслиo.k это свойство доступа, то вызовObject.defineProperty(o, "k", { set: undefined }) удалит сеттер, оставив уk только геттер, то есть сделает его доступным только для чтения. Если атрибут отсутствует в новом дескрипторе, то берётся значение атрибута из старого дескриптора (то есть не происходит неявного переопределения наundefined). Можно переключаться между разными типами дескрипторов (свойства данных или доступа). Например, если новый дескриптор — это дескриптор данных (сvalue илиwritable), то атрибутыget иset оригинального дескриптора будут удалены.

Атрибутwritable

Если атрибутwritable свойства установлен вfalse, свойство становится «незаписываемым». Ему невозможно будет присвоить новое значение.

js
var o = {}; // Создаём новый объектObject.defineProperty(o, "a", {  value: 37,  writable: false,});console.log(o.a); // Выведет 37o.a = 25; // Исключение не будет выброшено (будет выброшено только в// строгом режиме, даже если значение будет тем же самым)console.log(o.a); // Выведет 37. Присваивание не сработало.

Как видно в этом примере, попытка записи в незаписываемое свойство его не изменило, но и исключение так же не было выброшено.

Атрибутenumerable

Атрибутenumerable свойства определяет, просматривается ли свойство в циклеfor...in и методомObject.keys() или нет.

js
var o = {};Object.defineProperty(o, "a", { value: 1, enumerable: true });Object.defineProperty(o, "b", { value: 2, enumerable: false });// Атрибут enumerable по умолчанию установлен в falseObject.defineProperty(o, "c", { value: 3 });o.d = 4; // При создании свойства путём присваивания, атрибут enumerable// по умолчанию устанавливается в truefor (var i in o) {  console.log(i);}// Выведет 'a' и 'd' (порядок вывода не определён)Object.keys(o); // ['a', 'd']o.propertyIsEnumerable("a"); // trueo.propertyIsEnumerable("b"); // falseo.propertyIsEnumerable("c"); // false

Атрибутconfigurable

Атрибутconfigurable одновременно контролирует, может ли свойство быть удалено из объекта и могут ли быть изменены его атрибуты (кроме контроля изменения атрибутаwritable).

js
var o = {};Object.defineProperty(o, "a", {  get: function () {    return 1;  },  configurable: false,});Object.defineProperty(o, "a", { configurable: true }); // Выкинет TypeErrorObject.defineProperty(o, "a", { enumerable: true }); // Выкинет TypeErrorObject.defineProperty(o, "a", { set: function () {} }); // Выкинет TypeError (ранее свойство set дескриптора не было определено)Object.defineProperty(o, "a", {  get: function () {    return 1;  },}); // Выкинет TypeError (даже несмотря на то, что get делает то же, что и раньше)Object.defineProperty(o, "a", { value: 12 }); // Выкинет TypeErrorconsole.log(o.a); // Выведет 1delete o.a; // Ничего не произойдётconsole.log(o.a); // Выведет 1

Если бы атрибутconfigurable объектаo.a был установлен вtrue, никакие ошибки не были бы выброшены и в конце свойство было бы удалено.

Пример: добавление свойств и значений по умолчанию

Важно понимать, как устанавливаются значения по умолчанию атрибутам свойств. Часто существует разница между простым назначением значения посредством точечной нотации и использованием методаObject.defineProperty(), что и показывает пример ниже.

js
var o = {};o.a = 1;// Эквивалентно записи:Object.defineProperty(o, "a", {  value: 1,  writable: true,  configurable: true,  enumerable: true,});// С другой стороны,Object.defineProperty(o, "a", { value: 1 });// эквивалентно записи:Object.defineProperty(o, "a", {  value: 1,  writable: false,  configurable: false,  enumerable: false,});

Пример: пользовательские сеттеры и геттеры

Пример ниже показывает, как реализовать самоархивирующийся объект. При установке свойстваtemperature в массивarchive попадает запись журнала.

js
function Archiver() {  var temperature = null;  var archive = [];  Object.defineProperty(this, "temperature", {    get: function () {      console.log("get!");      return temperature;    },    set: function (value) {      temperature = value;      archive.push({ val: temperature });    },  });  this.getArchive = function () {    return archive;  };}var arc = new Archiver();arc.temperature; // 'get!'arc.temperature = 11;arc.temperature = 13;arc.getArchive(); // [{ val: 11 }, { val: 13 }]

Спецификации

Specification
ECMAScript® 2026 Language Specification
# sec-object.defineproperty

Совместимость с браузерами

Смотрите также

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp