RegExp.prototype.exec() - JavaScript

RegExp.prototype.exec()
=======================

Сводка
------

Метод **`exec()`** выполняет поиск сопоставления регулярного выражения в указанной строке. Возвращает массив с результатами или `null`.

Если целью выполнения является просто определить, проходит оно или нет, используйте метод `RegExp.prototype.test()`, либо метод строки `String.prototype.search()`.

Синтаксис
---------
```

regexObj.exec(str)
```

### Параметры

`str`

Строка, с которой производится сопоставление регулярного выражения.

### Возвращаемое значение

Если сопоставление успешно выполнилось, метод `exec()` возвращает массив и обновляет свойства объекта регулярного выражения. Возвращаемый массив в первом элементе содержит сопоставленный текст, а в последующих элементах — текст, захваченный при сопоставлении круглыми скобками.

Если сопоставление не удалось, метод `exec()` возвращает `null`.

Описание
--------

Рассмотрим следующий пример:

```js
// Сопоставляется с фразой «кайф, сплющь», за которой следует слово «вши»,
// игнорируя любые символы между ними. Запоминает слова «сплющь» и «вши».
// Игнорирует регистр символов.
var re = /кайф,\s(сплющь).+?(вши)/gi;
var result = re.exec("Эх, чужд кайф, сплющь объём вши, грызя цент.");
```

Таблица ниже показывает результаты выполнения данного примера:

|  |  |  |  |
| --- | --- | --- | --- |
| Объект | Свойство/Индекс | Описание | Пример |
| `result` | `[0]` | Все сопоставившиеся символы в строке. | `кайф, сплющь объём вши` |
| `[1], ...[*n*]` |
 Сопоставившиеся подстроки в круглых скобках, если они присутствуют.
 Количество возможных подстрок ничем не ограничено.
  | `[1] = сплющь[2] = вши` |
| `index` | Индекс сопоставления в строке, начинается с нуля. | `9` |
| `input` | Оригинальная строка. | `Эх, чужд кайф, сплющь объём вши, грызя цент.` |
| `re` | `lastIndex` |
 Индекс, с которого начнётся следующая попытка сопоставления. Если
 отсутствует флаг `"g"`, остаётся равным нулю.
  | `31` |
| `ignoreCase` |
 Указывает, что в регулярном выражении используется флаг игнорирования
 регистра `"i"`.
  | `true` |
| `global` |
 Указывает, что в регулярном выражении используется флаг глобального
 сопоставления `"g"`.
  | `true` |
| `multiline` |
 Указывает, что в регулярном выражении используется флаг сопоставления по
 нескольким строкам `"m"`.
  | `false` |
| `source` | Текст шаблона регулярного выражения. | `кайф,\s(сплющь).+?(вши)` |

Примеры
-------

### Пример: поиск последовательных сопоставлений

Если ваше регулярное выражение использует флаг `"g"`, вы можете использовать метод `exec()` несколько раз для нахождения последовательных сопоставлений в одной и той же строке. Если вы сделаете это, поиск начнётся по подстроке строки `str`, начало которой определяется свойством `lastIndex` регулярного выражения (метод `test()` также увеличивает свойство `lastIndex`). Например, предположим, что у вас есть следующий скрипт:

```js
var myRe = /аб\*/g;
var str = "аббвгдеабж";
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = "Найдено " + myArray[0] + ". ";
  msg += "Следующее сопоставление начнётся с позиции " + myRe.lastIndex;
  console.log(msg);
}
```

Этот скрипт выведет следующий текст:

```js
Найдено абб. Следующее сопоставление начнётся с позиции 3
Найдено аб. Следующее сопоставление начнётся с позиции 9
```

Примечание: не помещайте литерал регулярного выражения (или конструктор `RegExp`) внутрь условия `while`; это приведёт к бесконечному циклу, поскольку свойство `lastIndex` будет сбрасываться в ноль на каждой итерации цикла. Также убедитесь, что установлен флаг глобального сопоставления, в противном случае цикл будет бесконечным.

### Пример: использование метода `exec()` вместе с литералами регулярного выражения

Вы можете использовать метод `exec()` без создания объекта `RegExp`:

```js
var matches = /(привет \S+)/.exec("Это привет миру!");
console.log(matches[1]);
```

Скрипт выведет в журнал строку «привет миру!».

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype.exec |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Глава про регулярные выражения в руководстве по JavaScript
* `RegExp`


RegExp.prototype.global - JavaScript

RegExp.prototype.global
=======================

Сводка
------

Свойство **`global`** указывает, использовался ли в определении регулярного выражения флаг `"g"`. Свойство `global` является свойством только для чтения и принадлежит экземпляру регулярного выражения.

| Атрибуты свойства `RegExp.prototype.global` |
| --- |
| Записываемое | нет |
| Перечисляемое | нет |
| Настраиваемое | нет |

Описание
--------

Значение свойства `global` имеет тип `Boolean` и содержит `true`, если при определении регулярного выражения использовался флаг `"g"`; в противном случае оно содержит `false`. Флаг `"g"` указывает на то, что регулярное выражение должно проверять все возможные сопоставления в строке.

Вы не можете напрямую изменить это свойство.

Примеры
-------

### Пример: использование свойства `global`

```js
var regex = new RegExp("foo", "g");

console.log(regex.global); // true
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.global |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.lastIndex`
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`


RegExp.prototype.sticky - JavaScript

RegExp.prototype.sticky
=======================

Сводка
------

Свойство **`sticky`** отражает тот факт, является ли поиск «липким» (то есть, начинается ли он с индекса, на который указывает свойство `lastIndex` регулярного выражения). Свойство `sticky` является свойством только для чтения и принадлежит экземпляру регулярного выражения.

| Атрибуты свойства `RegExp.prototype.sticky` |
| --- |
| Записываемое | нет |
| Перечисляемое | нет |
| Настраиваемое | нет |

Описание
--------

Значение свойства **`sticky`** имеет тип `Boolean` и содержит `true`, если при определении регулярного выражения использовался флаг `"y",` в противном случае оно содержит `false`. Флаг `"y"` указывает на то, что регулярное выражение сопоставляется с целевой строкой начиная с позиции, на которую указывает его свойство `lastIndex` (и не пытается сопоставиться по любому более старшему индексу). Такое поведение позволяет эффективно использовать символ `"^"` сопоставления-с-началом в любом месте строки путём смены значения свойства `lastIndex`.

Вы не можете напрямую изменить это свойство.

Примеры
-------

### Пример: использование регулярных выражений с флагом «липучести»

Этот пример демонстрирует, как можно использовать флаг «липучести» регулярных выражений для сопоставления с отдельными строками многострочного ввода.

```js
var text = "Первая строка\nВторая строка";
var regex = /(\S+) строка\n?/y;

var match = regex.exec(text);
console.log(match[1]); // напечатает 'Первая'
console.log(regex.lastIndex); // напечатает '14'

var match2 = regex.exec(text);
console.log(match2[1]); // напечатает 'Вторая'
console.log(regex.lastIndex); // напечатает '27'

var match3 = regex.exec(text);
console.log(match3 === null); // напечатает 'true'
```

Проверка совместимости
----------------------

Во время выполнения можно проверить, поддерживается ли флаг «липучести», при помощи блока `try { … } catch { … }`. Для этого надо использовать либо выражение с `eval(…)`, либо конструктор `RegExp(строка регулярного выражения, строка-с-флагами)` (поскольку нотация `/регулярное выражение/флаги` обрабатывается во время компиляции, исключение будет выброшено до того, как выполнение достигнет блока `catch`). Например:

```js
var supports_sticky;
try {
  RegExp("", "y");
  supports_sticky = true;
} catch (e) {
  supports_sticky = false;
}
console.log(supports_sticky); // напечатает 'false' в Firefox 2 и 'true' в Firefox 3+
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.sticky |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.lastIndex`
* `RegExp.prototype.global`
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`


RegExp.prototype.unicode - JavaScript

RegExp.prototype.unicode
========================

Свойство unicode указывает, используется ли флаг «u» с регулярным выражением. Свойство unicode доступно только для чтения конкретного экземпляра регулярного выражения.

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

| Атрибуты свойства `RegExp.prototype.unicode` |
| --- |
| Записываемое | нет |
| Перечисляемое | нет |
| Настраиваемое | да |

Описание
--------

Значение unicode является `Boolean`. True, если используется флаг u, или false - противном случае. Флаг «u» позволяет использовать различные функции, связанные с Unicode. С флагом «u» любые escape-последовательности кода Unicode будут интерпретироваться как таковые, например.

Вы не можете напрямую изменить это свойство. Оно доступно только для чтения.

Примеры
-------

### Использование свойства `unicode`

```js
var regex = new RegExp("\u{61}", "u");

console.log(regex.unicode); // true
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.unicode |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.lastIndex`
* `RegExp.prototype.global`
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`


RegExp.lastIndex - JavaScript

RegExp.lastIndex
================

Сводка
------

Свойство **`lastIndex`** является целочисленным свойством регулярного выражения, доступным как для чтения, так и для записи, которое определяет индекс, с которого следует начинать следующее сопоставление.

| Атрибуты свойства `RegExp.lastIndex` |
| --- |
| Записываемое | да |
| Перечисляемое | нет |
| Настраиваемое | нет |

Синтаксис
---------
```

regExpObj.lastIndex
```

Описание
--------

Это свойство устанавливается только в том случае, если в регулярном выражении используется флаг `"g"`, указывающий на необходимость глобального поиска. Оно подчиняется следующим правилам:

* Если свойство `lastIndex` больше длины строки, методы `test()` и `exec()` завершатся с неудачей, а свойство `lastIndex` будет установлено в 0.
* Если свойство `lastIndex` равно длине строки и регулярное выражение сопоставляется с пустой строкой, то регулярное выражение начнёт сопоставляться, начиная с позиции `lastIndex`.
* Если свойство `lastIndex` равно длине строки и регулярное выражение не сопоставляется с пустой строкой, то регулярное выражение не соответствует входу и свойство `lastIndex` сбрасывается в 0.
* Во всех остальных случаях свойство `lastIndex` устанавливается в позицию, следующую за самым последним сопоставлением.
Примеры
-------

### Пример: использование свойства `lastIndex`

Рассмотрим следующую последовательность инструкций:

```js
var re = /(привет)?/g;
```

Сопоставляется с пустой строкой.

```js
console.log(re.exec("привет"));
console.log(re.lastIndex);
```

Выведет массив `["привет", "привет"]`, а свойство `lastIndex` будет равным 6.

```js
console.log(re.exec("привет"));
console.log(re.lastIndex);
```

Выведет массив `["", undefined]`, «пустой» массив, чей нулевой элемент является сопоставившейся строкой. В данном случае, ей является пустая строка, поскольку свойство `lastIndex` было равно 6 (и остаётся равным 6), а строка `"привет"` имеет длину 6.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-properties-of-regexp-instances |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.global`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`


RegExp.prototype.source - JavaScript

RegExp.prototype.source
=======================

Сводка
------

Свойство **`source`** возвращает строку, содержащую текст шаблона регулярного выражения без прямых слешей с обеих сторон и без флагов регулярного выражения.

Примеры
-------

### Пример: использование свойства `source`

```js
var regex = /fooBar/gi;

console.log(regex.source); // 'fooBar', не содержит прямые слеши /.../ и флаги 'ig'.
```

Начиная с ECMAScript 5, свойство `source` больше не возвращает пустую строку для пустых регулярных выражений. Вместо этого, возвращается строка" (?:)". Кроме того, теперь экранируются символы окончания строк (такие как, "\n").
```

new RegExp().source; // "(?:)"

new RegExp('\n').source === '\n';  // true, до появления ES5
new RegExp('\n').source === '\\n'; // true, начиная с ES5
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.source |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.prototype.flags`


RegExp.input ($_) - JavaScript

RegExp.input ($\_)
==================

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Нестандартное свойство **`input`** является статическим свойством регулярных выражений. Оно содержит строку, для которой произошло совпадение по регулярному выражению. Значение свойства также можно получить как `RegExp.$_`.

Синтаксис
---------
```

RegExp.input
RegExp.$_
```

Описание
--------

Поскольку свойство `input` статическое, к нему можно обратиться только как `RegExp.input` или `RegExp.$_`.

Значение данного свойства изменяется каждый раз при возникновении совпадений с регулярным выражением для новой строки.

Примеры
-------

### Использование `input` и `$_`

```js
var re = /hi/g;
re.test("hi there!");
RegExp.input; // "hi there!"
re.test("foo"); // новая проверка, совпадений нет
RegExp.$_; // "hi there!"
re.test("hi world!"); // новая проверка, совпадение есть
RegExp.$_; // "hi world!"
```

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

Не стандартизированной. Не является частью какой-либо спецификации.

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Non-standard
 `RegExp.lastMatch ($&)`
* Non-standard
 `RegExp.lastParen ($+)` (en-US)
* Non-standard
 `RegExp.leftContext ($`)` (en-US)
* Non-standard
 `RegExp.rightContext ($')` (en-US)
* Non-standard
 `RegExp.$1-$9`


RegExp.$1-$9 - JavaScript

RegExp.$1-$9
============

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Нестандартные свойства **$1, $2, $3, $4, $5, $6, $7, $8, $9** являются статическими и доступными только для чтения свойствами регулярных выражений, которые содержат найденные подстроки, обёрнутые в скобки.

Синтаксис
---------
```

RegExp.$1
RegExp.$2
RegExp.$3
RegExp.$4
RegExp.$5
RegExp.$6
RegExp.$7
RegExp.$8
RegExp.$9
```

Описание
--------

Свойства $1, ..., $9 являются статичными, они не являются свойствами конкретного объекта регулярного выражения, поэтому вы всегда можете использовать их как `RegExp.$1`, ..., `RegExp.$9`.

Значения этих свойств не доступны для изменения, они модифицируются всякий раз при успешном совпадении регулярного выражения.

Количество возможных подстрок в круглых скобках неограничено, но объект `RegExp` может содержать в себе только последние 9. Вы можете получить доступ ко всем подстрокам, совпавшим с выражениями внутри круглых скобок, с помощью индексов возвращённого массива.

Эти свойства могу использоваться при замене текста в методе `String.replace`. Когда используете его, не добавляйте их в `RegExp`. Пример ниже демонстрирует правильное применение. Когда круглые скобки не включены в регулярное выражение, код интерпретирует такие значения, как `$n` буквально, как литерал (n - положительное число).

Примеры
-------

### Использование `$n` со `String.replace`

Следующий код использует метод `replace()` строки `String`, чтобы преобразовать строку в формате *Имя Фамилия* в формат *Фамилия, Имя*. В коде замены текста используются `$1` и `$2` чтобы указать порядок вывода результата совпадений полученных при сравнивании с шаблоном регулярного выражения, имеющего круглые скобки.

```js
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
str.replace(re, "$2, $1"); // "Smith, John"
RegExp.$1; // "John"
RegExp.$2; // "Smith"
```

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

Не стандартизированной. Не является частью какой-либо спецификации

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Non-standard
 `RegExp.input ($_)`
* Non-standard
 `RegExp.lastMatch ($&)`
* Non-standard
 `RegExp.lastParen ($+)` (en-US)
* Non-standard
 `RegExp.leftContext ($`)` (en-US)
* Non-standard
 `RegExp.rightContext ($')` (en-US)


RegExp.prototype.ignoreCase - JavaScript

RegExp.prototype.ignoreCase
===========================

Сводка
------

Свойство **`ignoreCase`** указывает, использовался ли в определении регулярного выражения флаг `"i"`. Свойство `ignoreCase` является свойством только для чтения и принадлежит экземпляру регулярного выражения.

| Атрибуты свойства `RegExp.prototype.ignoreCase` |
| --- |
| Записываемое | нет |
| Перечисляемое | нет |
| Настраиваемое | нет |

Описание
--------

Значение свойства `ignoreCase` имеет тип `Boolean` и содержит `true`, если при определении регулярного выражения использовался флаг `"i"`; в противном случае оно содержит `false`. Флаг `"i"` указывает на то, что регистр символов в строке, с которой сопоставляется регулярное выражение, должен игнорироваться.

Вы не можете напрямую изменить это свойство.

Примеры
-------

### Пример: использование свойства `ignoreCase`

```js
var regex = new RegExp("foo", "i");

console.log(regex.ignoreCase); // true
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.ignorecase |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.lastIndex`
* `RegExp.prototype.global`
* `RegExp.prototype.multiline`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`


RegExp.prototype.multiline - JavaScript

RegExp.prototype.multiline
==========================

Сводка
------

Свойство **`multiline`** указывает, использовался ли в определении регулярного выражения флаг `"m"`. Свойство `multiline` является свойством только для чтения и принадлежит экземпляру регулярного выражения.

| Атрибуты свойства `RegExp.prototype.multiline` |
| --- |
| Записываемое | нет |
| Перечисляемое | нет |
| Настраиваемое | нет |

Описание
--------

Значение свойства `multiline` имеет тип `Boolean` и содержит `true`, если при определении регулярного выражения использовался флаг `"m"`; в противном случае оно содержит `false`. Флаг `"m"` указывает на то, что многострочная входная строка должна рассматриваться в виде нескольких строк. Например, если используется флаг `"m"`, специальные символы `"^"` и `"$"` меняют своё поведение: с установленным флагом они сопоставляются в началом / концом каждой строки в многострочной строке, а не с началом / концом всей многострочной строки.

Вы не можете напрямую изменить это свойство.

Примеры
-------

### Пример: использование свойства `multiline`

```js
var regex = new RegExp("foo", "m");

console.log(regex.multiline); // true
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-get-regexp.prototype.multiline |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `RegExp.lastIndex`
* `RegExp.prototype.global`
* `RegExp.prototype.ignoreCase`
* `RegExp.prototype.source`
* `RegExp.prototype.sticky`


RegExp.lastMatch ($&) - JavaScript

RegExp.lastMatch ($&)
=====================

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Нестандартное свойство **lastMatch** является доступным только для чтения статическим свойством регулярных выражений. Оно содержит последние совпавшие символы. Значение свойства также можно получить как `RegExp.$&`.

Синтаксис
---------
```

RegExp.lastMatch
RegExp['$&']
```

Описание
--------

Поскольку свойство `lastMatch` статическое, к нему можно обратиться только как `RegExp.lastMatch` или `RegExp['$&'].`

Значение свойства `lastMatch` доступно только для чтение и изменяется при успешном совпадении с регулярным выражением.

Поскольку использование символа "&" приведёт к выбрасыванию ошибки `SyntaxError`, обратиться к данному свойству с помощью точечной нотации(`RegExp.$&`) нельзя. Вместо этого стоит использовать скобочную нотацию (`RegExp['$&']`).

Примеры
-------

### Использование `lastMatch` и `$&`

```js
var re = /hi/g;
re.test("hi there!");
RegExp.lastMatch; // "hi"
RegExp["$&"]; // "hi"
```

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

Не стандартизированной. Не является частью какой-либо спецификации.

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Non-standard
 `RegExp.input ($_)`
* Non-standard
 `RegExp.lastParen ($+)` (en-US)
* Non-standard
 `RegExp.leftContext ($`)` (en-US)
* Non-standard
 `RegExp.rightContext ($')` (en-US)
* Non-standard
 `RegExp.$1-$9`


RegExp.prototype.test() - JavaScript

RegExp.prototype.test()
=======================

Сводка
------

Метод **`test()`** выполняет поиск сопоставления регулярного выражения указанной строке. Возвращает `true` или `false`.

Синтаксис
---------
```

regexObj.test(str)
```

### Параметры

`str`

Строка, с которой сопоставляется регулярное выражение.

### Возвращаемое значение

Логическое значение: `true` или `false`.

Описание
--------

Используйте метод `test()`, если вы просто хотите узнать, находится ли шаблон в строке (он почти аналогичен методу `String.prototype.search()`, только вместо индекса шаблона возвращает `true` или `false`); для получения дополнительной информации о сопоставлении (но за счёт более медленного выполнения) используйте метод `exec()` (он аналогичен методу `String.prototype.match()`). Как и при вызове метода `exec()` (или при совместном с ним вызове), метод `test()`, вызванный несколько раз на одном и том же экземпляре глобального регулярного выражения, будет начинать проверку с конца предыдущего сопоставления.

Примеры
-------

### Пример: использование метода `test()`

Следующий пример печатает сообщение, в зависимости от того, была ли проверка успешной:

```js
function testinput(re, str) {
  var midstring;
  if (re.test(str)) {
    midstring = " содержит ";
  } else {
    midstring = " не содержит ";
  }
  console.log(str + midstring + re.source);
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-regexp.prototype.test |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Глава про регулярные выражения в руководстве по JavaScript
* `RegExp`


Object.isSealed() - JavaScript

Object.isSealed()
=================

Сводка
------

Метод **`Object.isSealed()`** определяет, является ли объект запечатанным.

Синтаксис
---------
```

Object.isSealed(obj)
```

### Параметры

`obj`

Проверяемый объект.

Описание
--------

Возвращает `true`, если объект является запечатанным, иначе возвращает `false`. Объект является запечатанным, если он является не расширяемым и если все его свойства являются не настраиваемыми и, следовательно, не удаляемыми (но не обязательно не записываемыми).

Примеры
-------

```js
// По умолчанию объекты не запечатаны.
var empty = {};
assert(Object.isSealed(empty) === false);

// Если вы сделаете пустой объект не расширяемым, он по определению станет запечатанным.
Object.preventExtensions(empty);
assert(Object.isSealed(empty) === true);

// То же самое не верно для не пустого объекта, пока все его свойства не станут не настраиваемыми.
var hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
assert(Object.isSealed(hasProp) === false);

// Но сделав все его свойства не настраиваемыми, объект становится запечатанным.
Object.defineProperty(hasProp, "fee", { configurable: false });
assert(Object.isSealed(hasProp) === true);

// Простейшим способом запечатать объект, конечно, является использование метода Object.seal.
var sealed = {};
Object.seal(sealed);
assert(Object.isSealed(sealed) === true);

// Запечатанный объект по определению является не расширяемым.
assert(Object.isExtensible(sealed) === false);

// Запечатанный объект может быть замороженным, но это не всегда так.
assert(Object.isFrozen(sealed) === true); // все свойства также являются не записываемыми

var s2 = Object.seal({ p: 3 });
assert(Object.isFrozen(s2) === false); // свойство 'p' всё ещё записываемое

var s3 = Object.seal({
  get p() {
    return 0;
  },
});
assert(Object.isFrozen(s3) === true); // для свойств доступа значение имеет только их настраиваемость
```

Примечания
----------

В ES5, если аргумент метода не является объектом (является примитивным значением), будет выброшено исключение `TypeError`. В ES6 такой аргумент будет рассматриваться, как простой запечатанный объект и метод просто вернёт `true`.

```js
> Object.isSealed(1)
TypeError: 1 is not an object // код ES5

> Object.isSealed(1)
true                          // код ES6
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.issealed |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.seal()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`


Object.freeze() - JavaScript

Object.freeze()
===============

Метод **`Object.freeze()`** замораживает объект: это значит, что он предотвращает добавление новых свойств к объекту, удаление старых свойств из объекта и изменение существующих свойств или значения их атрибутов перечисляемости, настраиваемости и записываемости. В сущности, объект становится эффективно неизменным. Метод возвращает замороженный объект.

Синтаксис
---------
```

Object.freeze(obj)
```

### Параметры

`obj`

Объект для заморозки.

### Возвращаемое значение

Замороженный объект

Описание
--------

К замороженному объекту нельзя добавить никаких свойств, так же как и удалить свойства из замороженного объекта. Любые попытки сделать это потерпят неудачу, либо молча, либо выбросив исключение `TypeError` (как правило, но не обязательно, это происходит в строгом режиме (en-US)).

Значения свойств-данных не могут быть изменены. Свойства-доступы (геттеры и сеттеры) работают как положено (и всё ещё создают иллюзию, что вы изменили значение). Обратите внимание, что значения, являющиеся объектами, всё ещё могут быть изменены, если только они так же не были заморожены.

Примеры
-------

```js
var obj = {
  prop: function () {},
  foo: "bar",
};

// Можно добавлять новые свойства, существующие свойства можно изменять или удалять
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

// Оба объекта эквивалентны, а также возвращаемый объект будет заморожен.
// Необязательно сохранять возвращаемый объект при заморозке оригинала.
var o = Object.freeze(obj);

o === obj; // true
Object.isFrozen(obj); // === true;

// Теперь все изменения будут заканчиваться с ошибкой
obj.foo = "quux"; // тихо ничего не делает
obj.quaxxor = "the friendly duck"; // тихо не добавляет свойство

// ...а в строгом режиме такие попытки вызовут выброс исключения TypeError
function fail() {
  "use strict";
  obj.foo = "sparky"; // выбросит TypeError
  delete obj.quaxxor; // выбросит TypeError
  obj.sparky = "arf"; // выбросит TypeError
}

fail();

// Попытки внести изменения через метод Object.defineProperty также выбросят исключение
Object.defineProperty(obj, "ohai", { value: 17 }); // выбросит TypeError
Object.defineProperty(obj, "foo", { value: "eit" }); // выбросит TypeError
```

Следующий пример показывает, что значения-объекты в замороженном объекте могут быть изменены (заморозка неглубокая).

```js
obj = {
  internal: {},
};

Object.freeze(obj);
obj.internal.a = "значениеA";

obj.internal.a; // 'значениеA'

// Чтобы сделать объект obj полностью неизменяемым, замораживаем каждый объект в объекте obj.
// Для этого воспользуемся этой функцией.
function deepFreeze(obj) {
  // Получаем имена свойств из объекта obj
  var propNames = Object.getOwnPropertyNames(obj);

  // Замораживаем свойства для заморозки самого объекта
  propNames.forEach(function (name) {
    var prop = obj[name];

    // Заморозка свойства prop, если оно объект
    if (typeof prop == "object" && prop !== null) deepFreeze(prop);
  });

  // Заморозить сам объект obj (ничего не произойдёт, если он уже заморожен)
  return Object.freeze(obj);
}

obj2 = {
  internal: {},
};

deepFreeze(obj2);
obj2.internal.a = "другоеЗначение";
obj2.internal.a; // undefined
```

Примечания
----------

В ES5 если аргумент метода не является объектом (является примитивным значением), будет выброшено исключение `TypeError`. В ES2015 такой аргумент будет рассматриваться, как простой замороженный объект и метод его просто вернёт.

```js
> Object.freeze(1)
TypeError: 1 is not an object // код ES5

> Object.freeze(1)
1                             // код ES2015
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.freeze |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.isFrozen()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`


Object.prototype.__defineSetter__() - JavaScript

Object.prototype.\_\_defineSetter\_\_()
=======================================

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

 **Устарело:** Эта возможность была удалена из веб-стандартов. Хотя некоторые браузеры по-прежнему могут поддерживать её, она находится в процессе удаления. Не используйте её ни в старых, ни в новых проектах. Страницы или веб-приложения, использующие её, могут в любой момент сломаться.

Сводка
------

Метод **`__defineSetter__()`** привязывает свойство объекта к функции, вызываемой каждый раз при попытке установить значение этого свойства.

Синтаксис
---------
```

obj.__defineSetter__(prop, fun)
```

### Параметры

`prop`

Строка, содержащая имя свойства, привязываемого к заданной функции.

`fun`

Функция, вызываемая при попытке установить значение указанному свойству. Эта функция имеет вид:
```

function(val) { . . . }
```

`val`

Псевдоним переменной, содержащей значение, которое пытаются присвоить свойству `prop`.

Описание
--------

Метод `__defineSetter__()` позволяет определять сеттер (en-US) на уже существующем объекте.

Примеры
-------

```js
// Нестандартный и устаревший способ

const o = {};
o.\_\_defineSetter\_\_("value", function (val) {
  this.anotherValue = val;
});
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5

// Способ, совместимый со стандартом

// Использование оператора set
const o = {
  set value(val) {
    this.anotherValue = val;
  },
};
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5

// Использование метода Object.defineProperty()
const o = {};
Object.defineProperty(o, "value", {
  set: function (val) {
    this.anotherValue = val;
  },
});
o.value = 5;
console.log(o.value); // undefined
console.log(o.anotherValue); // 5
```

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

Не является частью какой-либо спецификации.

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.prototype.__defineGetter__()`
* оператор `set` (en-US)
* `Object.defineProperty()`
* `Object.prototype.__lookupGetter__()`
* `Object.prototype.__lookupSetter__()`
* Руководство по JS: определение геттеров и сеттеров
* [Запись в блоге] Устаревание \_\_defineGetter\_\_ и \_\_defineSetter\_\_ (англ.)
* Firefox bug 647423


Object.is() - JavaScript

Object.is()
===========

Сводка
------

Метод **`Object.is()`** определяет, являются ли два значения одинаковыми значениями (en-US).

Синтаксис
---------
```

var isSame = Object.is(value1, value2);
```

### Параметры

`value1`

Первое сравниваемое значение.

`value2`

Второе сравниваемое значение.

Описание
--------

Метод `Object.is()` определяет, являются ли два значения одинаковыми значениями (en-US). Два значения являются одинаковыми в следующих случаях:

* оба равны `undefined`
* оба равны `null`
* оба равны `true`, либо оба равны `false`
* оба являются строками с одинаковой длиной и одинаковыми символами
* оба являются одним и тем же объектом
* оба являются числами и
    + оба равны `+0`
    + оба равны `-0`
    + оба равны `NaN`
    + либо оба не равны нулю или `NaN` и оба имеют одинаковое значение

Поведение этого метода *не* аналогично оператору `==` (en-US). Оператор `==` (en-US) использует приведение типов обоих операндов (если они имеют различный тип) перед проверкой на равенство (в результате получается, что проверка `"" == false` даёт `true`), а метод `Object.is` приведение типов не выполняет.

Поведение этого метода *не* аналогично оператору `===` (en-US). Оператор `===` (en-US) (также как и оператор `==` (en-US)) считает числовые значения `-0` и `+0` равными, а значение `Number.NaN` не равным самому себе.

Примеры
-------

```js
Object.is("foo", "foo"); // true
Object.is(window, window); // true

Object.is("foo", "bar"); // false
Object.is([], []); // false

var test = { a: 1 };
Object.is(test, test); // true

Object.is(null, null); // true

// Специальные случаи
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0 / 0); // true
```

Полифил
-------

Метод `Object.is` предложен в дополнение к стандарту ECMA-262; поэтому он может быть недоступен в некоторых браузерах. Это можно обойти, вставив приведённый ниже фрагмент кода в начало ваших скриптов. Он позволит вам использовать метод `Object.is` в случаях, когда он не имеет родной поддержки браузером.
```

if (!Object.is) {
  Object.is = function(x, y) {
    // SameValue algorithm
    if (x === y) { // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // Step 6.a: NaN == NaN
      return x !== x && y !== y;
    }
  };
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.is |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Руководство по JavaScript: одинаковость (en-US) — сравнение всех трёх встроенных способов проверки на одинаковость


Object.prototype.isPrototypeOf() - JavaScript

Object.prototype.isPrototypeOf()
================================

Сводка
------

Метод **`isPrototypeOf()`** проверяет, входит ли объект в цепочку прототипов другого объекта.

**Примечание:** метод `isPrototypeOf()` отличается от оператора `instanceof`. Выражение "`object instanceof AFunction`" проверяет, присутствует ли в цепочке прототипов объекта `object` объект `AFunction.prototype`, а не сам объект `AFunction`.

Синтаксис
---------
```

prototypeObj.isPrototypeOf(object)
```

### Параметры

`prototypeObj`

Объект, проверяемый на каждую ссылку в цепочке прототипов аргумента **object**.

`object`

Объект, в чьей цепочке прототипов производится поиск.

Описание
--------

Метод `isPrototypeOf()` позволяет вам проверять, существует ли объект в цепочке прототипов другого объекта.

Например, рассмотрим следующую цепочку прототипов:

```js
function Fee() {
  // ...
}

function Fi() {
  // ...
}
Fi.prototype = new Fee();

function Fo() {
  // ...
}
Fo.prototype = new Fi();

function Fum() {
  // ...
}
Fum.prototype = new Fo();
```

Если позже вы создадите экземпляр объекта `Fum` и захотите проверить, что прототип `Fi` существует в цепочке прототипов `Fum`, вы можете сделать следующее:

```js
var fum = new Fum();
// ...

if (Fi.prototype.isPrototypeOf(fum)) {
  // здесь безопасно что-то делать
}
```

Таким образом, вместе с оператором `instanceof`, это особенно пригождается, если у вас есть код, который может работать только с объектами, имеющими определённую цепочку прототипов, к примеру, чтобы он мог гарантировать, что в объекте присутствуют определённые методы или свойства.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.isprototypeof |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `instanceof`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()`
* `Object.prototype.__proto__`


Object.getOwnPropertyDescriptor() - JavaScript

Object.getOwnPropertyDescriptor()
=================================

Сводка
------

Метод **`Object.getOwnPropertyDescriptor()`** возвращает дескриптор свойства для *собственного свойства* (то есть такого, которое находится непосредственно в объекте, а не получено через цепочку прототипов) переданного объекта.

Синтаксис
---------
```

Object.getOwnPropertyDescriptor(obj, prop)
```

### Параметры

`obj`

Объект, в котором ищется свойство.

`prop`

Имя свойства, чьё описание будет возвращено.

### Возвращаемое значение

Дескриптор переданного свойства, если оно присутствует в объекте, либо `undefined`, если его там нет.

Описание
--------

Этот метод позволяет просмотреть точное описание свойства. *Свойство* в JavaScript состоит из строкового имени и дескриптора свойства. Подробная информация о типах дескрипторов свойств и их атрибутах может быть найдена в описании метода `Object.defineProperty()`.

*Дескриптор свойства* — это запись с некоторыми из следующих атрибутов:

`value`

Значение, ассоциированное со свойством (только в дескрипторе данных).

`writable`

Значение `true`, если значение, ассоциированное со свойством, может быть изменено, иначе `false` (только в дескрипторе данных).

`get`

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

`set`

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

`configurable`

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

`enumerable`

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

Примеры
-------

```js
var o, d;

o = {
  get foo() {
    return 17;
  },
};
d = Object.getOwnPropertyDescriptor(o, "foo");
// d равен { configurable: true, enumerable: true, get: /\*функция геттера\*/, set: undefined }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d равен { configurable: true, enumerable: true, value: 42, writable: true }

o = {};
Object.defineProperty(o, "baz", {
  value: 8675309,
  writable: false,
  enumerable: false,
});
d = Object.getOwnPropertyDescriptor(o, "baz");
// d равен { value: 8675309, writable: false, enumerable: false, configurable: false }
```

Примечания
----------

В ES5, если первый аргумент метода не является объектом (является примитивным значением), будет выброшено исключение `TypeError`. В ES6 такой аргумент будет сначала приведён к объекту.

```js
> Object.getOwnPropertyDescriptor('foo', 0)
TypeError: "foo" is not an object  // код ES5

> Object.getOwnPropertyDescriptor('foo', 0)
{ configurable: false, enumerable: true, value: 'f', writable: false }  // код ES6
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertydescriptor |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.defineProperty()`


Object.create() - JavaScript

Object.create()
===============

Метод **`Object.create()`** создаёт новый объект с указанным прототипом и свойствами.

Синтаксис
---------
```

Object.create(proto[, propertiesObject])
```

### Параметры

`proto`

Объект, который станет прототипом вновь созданного объекта.

`propertiesObject`

Необязательный параметр. Если указан и не равен `undefined`, должен быть объектом, чьи собственные перечисляемые свойства (то есть такие, которые определены на самом объекте, а не унаследованы по цепочке прототипов) указывают дескрипторы свойств, добавляемых в новый объект. Имена добавляемых свойств совпадают с именами свойств в этом объекте. Эти свойства соответствуют второму аргументу метода `Object.defineProperties()`.

### Возвращаемые значения

Новый объект с заданным прототипом и свойствами

### Выбрасываемые исключения

Выбрасывает исключение `TypeError`, если параметр `proto` не является `null` или объектом (исключение составляют объекты-обёртки примитивных типов).

Примеры
-------

### Пример: классическое наследование с `Object.create()`

Ниже показан пример использования `Object.create()` для имитации классического наследования. Это пример одиночного наследования, поскольку только его поддерживает JavaScript.

```js
// Shape — суперкласс
function Shape() {
  this.x = 0;
  this.y = 0;
}

// метод суперкласса
Shape.prototype.move = function (x, y) {
  this.x += x;
  this.y += y;
  console.info("Фигура переместилась.");
};

// Rectangle — подкласс
function Rectangle() {
  Shape.call(this); // вызываем конструктор суперкласса
}

// подкласс расширяет суперкласс
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log(
  "Является ли rect экземпляром Rectangle? " + (rect instanceof Rectangle),
); // true
console.log("Является ли rect экземпляром Shape? " + (rect instanceof Shape)); // true
rect.move(1, 1); // выведет 'Фигура переместилась.'
```

Если вы хотите наследоваться от нескольких объектов, то это возможно сделать при помощи примесей.

```js
function MyClass() {
  SuperClass.call(this);
  OtherSuperClass.call(this);
}

MyClass.prototype = Object.create(SuperClass.prototype); // наследование
mixin(MyClass.prototype, OtherSuperClass.prototype); // примешивание

MyClass.prototype.myMethod = function () {
  // что-то делаем
};
```

Функция примешивания должна копировать функции из прототипа суперкласса в прототип подкласса, она должна предоставляться пользователем. Примером примеси может служить функция jQuery.extend().

### Пример: использование аргумента `propertiesObject` с `Object.create()`

```js
var o;

// создаём объект с нулевым прототипом
o = Object.create(null);

o = {};
// эквивалентно этому:
o = Object.create(Object.prototype);

// В этом примере мы создаём объект с несколькими свойствами.
// (Обратите внимание, что второй параметр отображает ключи на \*дескрипторы свойств\*.)
o = Object.create(Object.prototype, {
  // foo является рядовым 'свойством-значением'
  foo: { writable: true, configurable: true, value: "привет" },
  // bar является свойством с геттером и сеттером (свойством доступа)
  bar: {
    configurable: false,
    get: function () {
      return 10;
    },
    set: function (value) {
      console.log("Установка `o.bar` в", value);
    },
    /\* при использовании методов доступа ES5 наш код мог бы выглядеть так:
 get function() { return 10; },
 set function(value) { console.log('Установка `o.bar` в', value); } \*/
  },
});

function Constructor() {}
o = new Constructor();
// эквивалентно этому:
o = Object.create(Constructor.prototype);
// Конечно, если бы в функции Constructor был бы реальный код инициализации,
// метод с Object.create() не был бы эквивалентным

// создаём новый объект, чей прототип является новым пустым объектом
// и добавляем простое свойство 'p' со значением 42
o = Object.create({}, { p: { value: 42 } });

// по умолчанию свойства НЕ ЯВЛЯЮТСЯ записываемыми, перечисляемыми или настраиваемыми:
o.p = 24;
o.p;
// 42

o.q = 12;
for (var prop in o) {
  console.log(prop);
}
// 'q'

delete o.p;
// false

// для определения свойства ES3
o2 = Object.create(
  {},
  {
    p: {
      value: 42,
      writable: true,
      enumerable: true,
      configurable: true,
    },
  },
);
```

Полифил
-------

Для этого полифила необходима правильно работающая Object.prototype.hasOwnProperty.

```js
if (typeof Object.create != "function") {
  // Этапы производства ECMA-262, издание 5, 15.2.3.5
  // Ссылка: http://es5.github.io/#x15.2.3.5
  Object.create = (function () {
    // Чтобы сэкономить память, используйте общий конструктор
    function Temp() {}

    // делает безопасную ссылку на Object.prototype.hasOwnProperty
    var hasOwn = Object.prototype.hasOwnProperty;

    return function (O) {
      // 1. Если Type(O) не является Object or Null выдаётся исключение TypeError.
      if (typeof O != "object") {
        throw TypeError("Object prototype may only be an Object or null");
      }

      // 2. Пусть obj будет результатом создания нового объекта, как если бы
      // выражение new Object(), где Object является стандартным встроенным
      // конструктором с таким именем
      // 3. Установите для внутреннего свойства [[Prototype]] объекта obj значение O.
      Temp.prototype = O;
      var obj = new Temp();
      Temp.prototype = null; // Давайте не будем держать случайные ссылки на О...

      // 4. Если аргумент Properties присутствует и не определён, добавляем
      // собственные свойства к obj, как будто вызывая стандартную встроенную
      // функцию Object.defineProperties с аргументами obj и
      // Properties.
      if (arguments.length > 1) {
        // Object.defineProperties делает ToObject своим первым аргументом.
        var Properties = Object(arguments[1]);
        for (var prop in Properties) {
          if (hasOwn.call(Properties, prop)) {
            obj[prop] = Properties[prop];
          }
        }
      }

      // 5. Возвращает obj
      return obj;
    };
  })();
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.create |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.defineProperty()`
* `Object.defineProperties()`
* `Object.prototype.isPrototypeOf()`
* Запись в блоге Джона Резига о getPrototypeOf()


Object.isFrozen() - JavaScript

Object.isFrozen()
=================

Сводка
------

Метод **`Object.isFrozen()`** определяет, был ли объект заморожен.

Синтаксис
---------
```

Object.isFrozen(obj)
```

### Параметры

`obj`

Проверяемый объект.

Описание
--------

Объект является замороженным только в том случае, если он не расширяем, все его свойства являются не настраиваемыми и все его свойства данных (то есть такие, которые не являются свойствами доступа с функциями сеттера или геттера) являются не записываемыми.

Примеры
-------

```js
// Новый объект является расширяемым, так что он не заморожен.
assert(Object.isFrozen({}) === false);

// Пустой не расширяемый объект по определению заморожен.
var vacuouslyFrozen = Object.preventExtensions({});
assert(Object.isFrozen(vacuouslyFrozen) === true);

// Новый объект с одним свойством является расширяемым, поэтому он не заморожен.
var oneProp = { p: 42 };
assert(Object.isFrozen(oneProp) === false);

// Предотвращение расширения объекта всё ещё не делает его замороженным,
// поскольку свойство всё ещё остаётся настраиваемым (и записываемым).
Object.preventExtensions(oneProp);
assert(Object.isFrozen(oneProp) === false);

// ...но при удалении этого свойства объект становится замороженным по определению.
delete oneProp.p;
assert(Object.isFrozen(oneProp) === true);

// Не расширяемый объект с не записываемым, но всё ещё настраиваемым свойством, не является замороженным.
var nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", { writable: false }); // делаем свойство не записываемым
assert(Object.isFrozen(nonWritable) === false);

// Изменение свойства на не настраиваемое делает объект замороженным.
Object.defineProperty(nonWritable, "e", { configurable: false }); // делаем свойство не настраиваемым
assert(Object.isFrozen(nonWritable) === true);

// Не расширяемый объект с не настраиваемым, но всё ещё записываемым свойством, также не является замороженным.
var nonConfigurable = { release: "кракен!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", { configurable: false });
assert(Object.isFrozen(nonConfigurable) === false);

// Изменение свойства на не записываемое делает объект замороженным.
Object.defineProperty(nonConfigurable, "release", { writable: false });
assert(Object.isFrozen(nonConfigurable) === true);

// Не расширяемый объект с настраиваемым свойством доступа не является замороженным.
var accessor = {
  get food() {
    return "ням";
  },
};
Object.preventExtensions(accessor);
assert(Object.isFrozen(accessor) === false);

// ...но сделав это свойство не настраиваемым, объект становится замороженным.
Object.defineProperty(accessor, "food", { configurable: false });
assert(Object.isFrozen(accessor) === true);

// Самым же простым способом заморозить объект можно через вызов на нём метода Object.freeze.
var frozen = { 1: 81 };
assert(Object.isFrozen(frozen) === false);
Object.freeze(frozen);
assert(Object.isFrozen(frozen) === true);

// По определению, замороженный объект является не расширяемым.
assert(Object.isExtensible(frozen) === false);

// Также, по определению, замороженный объект является запечатанным.
assert(Object.isSealed(frozen) === true);
```

Примечания
----------

В ES5, если аргумент метода не является объектом (является примитивным значением), будет выброшено исключение `TypeError`. В ES6 такой аргумент будет рассматриваться, как простой замороженный объект и метод просто вернёт `true`.

```js
> Object.isFrozen(1)
TypeError: 1 is not an object // код ES5

> Object.isFrozen(1)
true                          // код ES6
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.isfrozen |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.freeze()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`


Object.defineProperty() - JavaScript

Object.defineProperty()
=======================

Сводка
------

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

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

Синтаксис
---------

```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` только в том случае, если значение, ассоциированное со свойством, может быть изменено с помощью оператора присваивания (en-US).
 **Значение по умолчанию установлено в `false`.**

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

`get`

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

`set`

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

Имейте в виду, что эти ключи не обязательно должны принадлежать самому дескриптору свойства, если они унаследованы, они так же будут приниматься во внимание. Для сохранения этих ключей по умолчанию неизменными, вы можете заранее заморозить `Object.prototype` (en-US), явно определив все ключи, либо установить свойство `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); // Выведет 37
o.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 по умолчанию установлен в false
Object.defineProperty(o, "c", { value: 3 });

o.d = 4; // При создании свойства путём присваивания, атрибут enumerable
// по умолчанию устанавливается в true

for (var i in o) {
  console.log(i);
}
// Выведет 'a' и 'd' (порядок вывода не определён)

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.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 }); // Выкинет TypeError
Object.defineProperty(o, "a", { enumerable: true }); // Выкинет TypeError
Object.defineProperty(o, "a", { set: function () {} }); // Выкинет TypeError (ранее свойство set дескриптора не было определено)
Object.defineProperty(o, "a", {
  get: function () {
    return 1;
  },
}); // Выкинет TypeError (даже несмотря на то, что get делает то же, что и раньше)
Object.defineProperty(o, "a", { value: 12 }); // Выкинет TypeError

console.log(o.a); // Выведет 1
delete 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 Language Specification # sec-object.defineproperty |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Перечисляемость и собственность свойств (en-US)
* `Object.defineProperties()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.getOwnPropertyDescriptor()`
* `get`
* `set`
* `Object.create()`
* `Reflect.defineProperty()`


Object.prototype.hasOwnProperty() - JavaScript

Object.prototype.hasOwnProperty()
=================================

Сводка
------

Метод **`hasOwnProperty()`** возвращает логическое значение, указывающее, содержит ли объект указанное свойство.

Синтаксис
---------
```

obj.hasOwnProperty(prop)
```

### Параметры

`prop`

Имя проверяемого свойства.

Описание
--------

Каждый объект, произошедший от `Object`, наследует метод `hasOwnProperty`. Этот метод может использоваться для определения того, содержит ли объект указанное свойство в качестве собственного свойства объекта; в отличие от оператора `in`, этот метод не проверяет существование свойств в цепочке прототипов объекта.

Примеры
-------

### Пример: использование `hasOwnProperty` для проверки существования свойства

В следующем примере определяется, содержит ли объект `o` свойство с именем `prop`:

```js
o = new Object();
o.prop = "существует";

function changeO() {
  o.newprop = o.prop;
  delete o.prop;
}

o.hasOwnProperty("prop"); // вернёт true
changeO();
o.hasOwnProperty("prop"); // вернёт false
```

### Пример: собственные и унаследованные свойства

Следующий пример показывает разницу между собственными свойствами и свойствами, унаследованными через цепочку прототипов:

```js
o = new Object();
o.prop = "существует";
o.hasOwnProperty("prop"); // вернёт true
o.hasOwnProperty("toString"); // вернёт false
o.hasOwnProperty("hasOwnProperty"); // вернёт false
```

### Пример: обход свойств объекта

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

```js
var buz = {
  fog: "stack",
};

for (var name in buz) {
  if (buz.hasOwnProperty(name)) {
    alert("это точно туман (" + name + "). Значение: " + buz[name]);
  } else {
    alert(name); // toString или что-то ещё
  }
}
```

### Пример: `hasOwnProperty` как свойство

JavaScript не защищает имя свойства `hasOwnProperty`; таким образом, вполне может существовать объект с таким свойством, поэтому для получения правильного результата нужно использовать *внешний* метод `hasOwnProperty`:

```js
var foo = {
  hasOwnProperty: function () {
    return false;
  },
  bar: "Тут драконы",
};

foo.hasOwnProperty("bar"); // всегда возвращает false

// Используем метод hasOwnProperty другого объекта и вызываем его с передачей foo в качестве this
({}).hasOwnProperty.call(foo, "bar"); // true

// Также для этих целей можно использовать свойство hasOwnProperty из прототипа Object
Object.prototype.hasOwnProperty.call(foo, "bar"); // true
```

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

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.hasownproperty |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Перечисляемость и собственность свойств (en-US)
* `Object.getOwnPropertyNames()`
* `for...in`
* `in`
* Руководство по JavaScript: повторное наследование (en-US)


Object.getOwnPropertySymbols() - JavaScript

Object.getOwnPropertySymbols()
==============================

Метод **`Object.getOwnPropertySymbols()`** возвращает массив всех символьных свойств, найденных непосредственно на переданном объекте.

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

Синтаксис
---------

```js
Object.getOwnPropertySymbols(obj);
```

### Параметры

`obj`

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

### Возвращаемое значение

Массив всех свойств символа, найденных прямо на данном объекте.

Описание
--------

Подобно методу `Object.getOwnPropertyNames()`, вы можете получить все символьные свойства указанного объекта в качестве массива символов. Обратите внимание, что метод `Object.getOwnPropertyNames()` сам не возвращает символьные свойства объекта, он возвращает только строковые свойства.

Поскольку изначально никакой объект не содержит собственных символьных свойств, метод `Object.getOwnPropertySymbols()` будет возвращать пустой массив, пока вы не установите символьные свойства на вашем объекте.

Примеры
-------

```js
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");

obj[a] = "localSymbol";
obj[b] = "globalSymbol";

var objectSymbols = Object.getOwnPropertySymbols(obj);

console.log(objectSymbols.length); // 2
console.log(objectSymbols); // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]); // Symbol(a)
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertysymbols |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.getOwnPropertyNames()`
* `Symbol`


Object.assign() - JavaScript

Object.assign()
===============

Метод **`Object.assign()`** используется для копирования значений всех собственных перечисляемых свойств из одного или более исходных объектов в целевой объект. После копирования он возвращает целевой объект.

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

Синтаксис
---------
```

Object.assign(target, ...sources)
```

### Параметры

`target`

Целевой объект.

`sources`

Исходные объекты.

### Возвращаемое значение

Возвращается получившийся целевой объект.

Описание
--------

Метод `Object.assign()` копирует из исходных объектов в целевой объект только *перечисляемые* и *собственные* свойства. Он использует внутренний метод `[[Get]]` на исходных объектах и внутренний метод `[[Set]]` на целевом объекте, так что он также вызывает геттеры и сеттеры. Именно поэтому он *присваивает* свойства вместо простого копирования или определения новых свойств. Это поведение может сделать метод непригодным для вливания новых свойств в прототип, если вливаемые исходные объекты содержат геттеры. Вместо него для копирования в прототипы определений свойств, включая признак их перечисляемости, следует использовать методы `Object.getOwnPropertyDescriptor()` и `Object.defineProperty()`.

Копируются свойства типов как `String`, так и `Symbol`.

В случае возникновения ошибки, например, когда свойство является незаписываемым, возбуждается исключение `TypeError`, а целевой объект `target` остаётся неизменным.

Обратите внимание, что метод `Object.assign()` не выкидывает исключения, если в качестве исходных значений выступают `null` или `undefined`.

Примеры
-------

### Пример: клонирование объекта

```js
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
```

### Пример: слияние объектов

```js
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, изменился и сам целевой объект.
```

### Пример: копирование символьных свойств

```js
var o1 = { a: 1 };
var o2 = { [Symbol("foo")]: 2 };

var obj = Object.assign({}, o1, o2);
console.log(obj); // { a: 1, [Symbol("foo")]: 2 }
```

### Пример: наследуемые и неперечисляемые свойства не копируются

```js
var obj = Object.create(
  { foo: 1 },
  {
    // foo является унаследованным свойством.
    bar: {
      value: 2, // bar является неперечисляемым свойством.
    },
    baz: {
      value: 3,
      enumerable: true, // baz является собственным перечисляемым свойством.
    },
  },
);

var copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }
```

### Пример: примитивы оборачиваются в объекты

```js
var v1 = "123";
var v2 = true;
var v3 = 10;
var v4 = Symbol("foo");

var obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// Примитивы будут обёрнуты, а null и undefined - проигнорированы.
// Обратите внимание, что собственные перечисляемые свойства имеет только обёртка над строкой.
console.log(obj); // { "0": "1", "1": "2", "2": "3" }
```

### Пример: исключения прерывают текущую задачу копирования

```js
var target = Object.defineProperty({}, "foo", {
  value: 1,
  writable: false,
}); // target.foo является свойством только-для-чтения

Object.assign(target, { bar: 2 }, { foo2: 3, foo: 3, foo3: 3 }, { baz: 4 });
// TypeError: "foo" is read-only
// При присваивании свойству target.foo выбрасывается исключение

console.log(target.bar); // 2, первый исходный объект успешно скопировался.
console.log(target.foo2); // 3, первое свойство второго исходного объекта успешно скопировалось.
console.log(target.foo); // 1, здесь было выброшено исключение.
console.log(target.foo3); // undefined, метод assign завершился, свойство foo3 не скопировалось.
console.log(target.baz); // undefined, третий исходный объект так же не скопировался.
```

### Пример: копирование методов доступа

```js
var obj = {
  foo: 1,
  get bar() {
    return 2;
  },
};

var copy = Object.assign({}, obj);
console.log(copy);
// { foo: 1, bar: 2 }, значением свойства copy.bar является значение, возвращаемое геттером obj.bar.

// Такой вариант функции присваивания позволяет копировать методы доступа.
function myAssign(target, ...sources) {
  sources.forEach((source) => {
    Object.defineProperties(
      target,
      Object.keys(source).reduce((descriptors, key) => {
        descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
        return descriptors;
      }, {}),
    );
  });
  return target;
}

var copy = myAssign({}, obj);
console.log(copy);
// { foo:1, get bar() { return 2 } }
```

Полифил
-------

Этот полифил не поддерживает символьные свойства, поскольку ES5 всё равно не поддерживает символы:

```js
if (!Object.assign) {
  Object.defineProperty(Object, "assign", {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function (target, firstSource) {
      "use strict";
      if (target === undefined || target === null) {
        throw new TypeError("Cannot convert first argument to object");
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }

        var keysArray = Object.keys(Object(nextSource));
        for (
          var nextIndex = 0, len = keysArray.length;
          nextIndex < len;
          nextIndex++
        ) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    },
  });
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.assign |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.defineProperties()`


Object.prototype.toString() - JavaScript

Object.prototype.toString()
===========================

Метод **`toString()`** возвращает строку, представляющую объект.

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

Синтаксис
---------
```

obj.toString()
```

### Возвращаемое значение

Строка, представляющая объект.

Описание
--------

Каждый объект имеет метод `toString()`, автоматически вызывающийся, когда объект должен быть представлен в виде текстового значения или когда объект участвует в выражении, где ожидается строка. По умолчанию, метод `toString()` наследуется каждым объектом, произошедшим от объекта `Object`. Если этот метод не переопределён в пользовательском объекте, `toString()` возвращает строку вида "[object *тип*]", где `тип` — это тип объекта. Это иллюстрирует следующий код:

```js
var o = new Object();
o.toString(); // вернёт [object Object]
```

**Примечание:** начиная с JavaScript 1.8.5, метод `toString()`, вызванный на `null`, возвращает строку `[object Null]`, а вызванный для `undefined`, возвращает строку `[object Undefined]`, как определено в 5-м издании ECMAScript и последующих исправлениях. Смотрите пример использование метода toString() для определения типа объекта.

Примеры
-------

### Пример: переопределение метода `toString` по умолчанию

Вы можете создать функцию, которая будет вызываться вместо метода `toString()` по умолчанию. Метод `toString()` не принимает аргументов и должен возвращать строку. Создаваемый вами метод `toString()` может возвращать любую строку, какую вы захотите, но он будет наиболее полезным, если будет возвращать информацию об объекте.

Следующий код определяет объект `Dog` и создаёт `theDog`, объект типа `Dog`:

```js
function Dog(name, breed, color, sex) {
  this.name = name;
  this.breed = breed;
  this.color = color;
  this.sex = sex;
}

theDog = new Dog("Болтушка", "лабрадор", "шоколадный", "девочка");
```

Если вы вызовете метод `toString()` на этом пользовательском объекте, он вернёт значение по умолчанию, унаследованное от `Object`:

```js
theDog.toString(); // вернёт [object Object]
```

Следующий код создаёт и присваивает метод `dogToString()`, переопределяющий метод `toString()` по умолчанию. Эта функция генерирует строку, содержащую кличку, породу, цвет и пол объекта, в форме "`свойство = значение;`".

```js
Dog.prototype.toString = function dogToString() {
  var ret =
    "Собачка " +
    this.name +
    " - " +
    this.sex +
    ", " +
    this.color +
    " " +
    this.breed;
  return ret;
};
```

или

```js
Dog.prototype.toString = function dogToString() {
  return `Dog ${this.name} is a ${this.sex} ${this.color} ${this.breed}`;
};
```

После объявления этого метода, при любом использовании переменной `theDog` в строковом контексте, JavaScript будет автоматически вызывать функцию `dogToString()`, возвращающую следующую строку:
```

Собачка Болтушка - девочка, шоколадный лабрадор
```

### Пример: использование метода `toString` для определения типа объекта

Метод `toString()` можно использовать с любым объектом для получения его класса. Для использования метода `Object.prototype.toString()` с любым объектом, вам необходимо вызвать на нём функции `Function.prototype.call()` или `Function.prototype.apply()`, передав объект, который вы хотите исследовать, первым параметром `thisArg`.

```js
var toString = Object.prototype.toString;

toString.call(new Date()); // [object Date]
toString.call(new String()); // [object String]
toString.call(Math); // [object Math]

// Начиная с JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tostring |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.prototype.toSource()` (en-US)
* `Object.prototype.valueOf()`
* `Number.prototype.toString()`
* `Symbol.toPrimitive`


Object.prototype.__lookupSetter__() - JavaScript

Object.prototype.\_\_lookupSetter\_\_()
=======================================

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

 **Устарело:** Эта возможность была удалена из веб-стандартов. Хотя некоторые браузеры по-прежнему могут поддерживать её, она находится в процессе удаления. Не используйте её ни в старых, ни в новых проектах. Страницы или веб-приложения, использующие её, могут в любой момент сломаться.

Сводка
------

Метод **`__lookupSetter__()`** возвращает функцию, привязанную к сеттеру указанного свойства.

Синтаксис
---------
```

obj.__lookupSetter__(sprop)
```

### Параметры

`sprop`

Строка, содержащая имя свойства, чей сеттер должен быть возвращён.

Описание
--------

Если для свойства объекта был определён сеттер, то на него невозможно сослаться через это свойство, поскольку оно ссылается на возвращаемое значение сеттера. Метод `__lookupSetter__()` может использоваться для получения ссылки на сеттер.

Сегодня это возможно сделать стандартным способом через `Object.getOwnPropertyDescriptor()`.

Примеры
-------

```js
var obj = {
  set foo(value) {
    return (this.bar = value);
  },
};

// Нестандартный и устаревший способ
obj.\_\_lookupSetter\_\_("foo");
// (function(value) { this.bar = value; })

// Способ, совместимый со стандартом
Object.getOwnPropertyDescriptor(obj, "foo").set;
// (function(value) { this.bar = value; })
```

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

Не является частью какой-либо спецификации.

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.prototype.__lookupGetter__()`
* оператор `set` (en-US)
* `Object.getOwnPropertyDescriptor()` и `Object.getPrototypeOf()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* Руководство по JS: определение геттеров и сеттеров


Object.keys() - JavaScript

Object.keys()
=============

Сводка
------

Метод **`Object.keys()`** возвращает массив из собственных перечисляемых свойств переданного объекта, в том же порядке, в котором они бы обходились циклом `for...in` (разница между циклом и методом в том, что цикл перечисляет свойства и из цепочки прототипов).

Синтаксис
---------
```

Object.keys(obj)
```

### Параметры

`obj`

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

Описание
--------

Метод `Object.keys` возвращает массив строковых элементов, соответствующих именам перечисляемых свойств, найденных непосредственно в самом объекте. Порядок свойств такой же, как и при ручном перечислении свойств в объекте через цикл.

Примеры
-------

```js
var arr = ["a", "b", "c"];
console.log(Object.keys(arr)); // консоль: ['0', '1', '2']

// Массивоподобный объект
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.keys(obj)); // консоль: ['0', '1', '2']

// Массивоподобный объект со случайным порядком ключей
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.keys(an_obj)); // консоль: ['2', '7', '100']

// Свойство getFoo является не перечисляемым свойством
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  },
);
my_obj.foo = 1;

console.log(Object.keys(my_obj)); // консоль: ['foo']
```

Если вы хотите увидеть все свойства, а не только перечисляемые, смотрите метод `Object.getOwnPropertyNames()`.

Примечания
----------

В ES5, если аргумент метода не является объектом (является примитивным значением), будет выброшено исключение `TypeError`. В ES2015 такой аргумент будет приведён к объекту.

```js
> Object.keys('foo')
TypeError: 'foo' is not an object // код ES5

> Object.keys('foo')
['0', '1', '2']                   // код ES2015
```

Полифил
-------

Для добавления поддержки совместимого метода `Object.keys` в старых окружениях, которые его ещё не реализуют, скопируйте следующий кусок кода:

```js
// From https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global\_Objects/Object/keys
if (!Object.keys) {
  Object.keys = (function () {
    "use strict";
    var hasOwnProperty = Object.prototype.hasOwnProperty,
      hasDontEnumBug = !{ toString: null }.propertyIsEnumerable("toString"),
      dontEnums = [
        "toString",
        "toLocaleString",
        "valueOf",
        "hasOwnProperty",
        "isPrototypeOf",
        "propertyIsEnumerable",
        "constructor",
      ],
      dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (
        typeof obj !== "object" &&
        (typeof obj !== "function" || obj === null)
      ) {
        throw new TypeError("Object.keys called on non-object");
      }

      var result = [],
        prop,
        i;

      for (prop in obj) {
        if (hasOwnProperty.call(obj, prop)) {
          result.push(prop);
        }
      }

      if (hasDontEnumBug) {
        for (i = 0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) {
            result.push(dontEnums[i]);
          }
        }
      }
      return result;
    };
  })();
}
```

Пожалуйста, обратите внимание, что вышеприведённый код в IE7 (и, может быть, в IE8) включает и не перечисляемые ключи, если объект передаётся из другого окна.

Более простой полифил может быть найден в статье Javascript - Object.keys Browser Compatibility (англ.).

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.keys |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Перечисляемость и собственность свойств (en-US)
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`


Object.getPrototypeOf() - JavaScript

Object.getPrototypeOf()
=======================

Сводка
------

Метод **`Object.getPrototypeOf()`** возвращает прототип (то есть, внутреннее свойство `[[Prototype]]`) указанного объекта.

Синтаксис
---------
```

Object.getPrototypeOf(obj)
```

### Параметры

`obj`

Объект, чей прототип будет возвращён.

Примеры
-------

```js
var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true
```

```js
> Object.getPrototypeOf('foo')
TypeError: "foo" is not an object  // код ES5
> Object.getPrototypeOf('foo')
String.prototype                   // код ES6
```

Примечания
----------

В ES5, если параметр `obj` не является объектом, будет выброшено исключение `TypeError`. В ES6, параметр будет приведён к объекту `Object`.

```js
> Object.getPrototypeOf('foo')
TypeError: "foo" is not an object  // код ES5
> Object.getPrototypeOf('foo')
String.prototype                   // код ES6
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getprototypeof |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### Примечания по Opera

Хотя старые версии Opera и не поддерживают метод `Object.getPrototypeOf()`, Opera поддерживает нестандартное свойство `Object.prototype.__proto__`, начиная с версии Opera 10.50.

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

* `Object.prototype.isPrototypeOf()`
* `Object.setPrototypeOf()`
Экспериментальная возможность
* `Object.prototype.__proto__`
* Запись в блоге Джона Резига о getPrototypeOf()


Object.prototype.propertyIsEnumerable() - JavaScript

Object.prototype.propertyIsEnumerable()
=======================================

Сводка
------

Метод **`propertyIsEnumerable()`** возвращает логическое значение, указывающее, является ли указанное свойство перечисляемым.

Синтаксис
---------
```

obj.propertyIsEnumerable(prop)
```

### Параметры

`prop`

Имя проверяемого свойства.

Описание
--------

Каждый объект имеет метод `propertyIsEnumerable`. Этот метод может определять, является ли указанное свойство в объекте перечисляемым в цикле `for...in`, за исключением свойств, унаследованных из цепочки прототипов. Если объект не имеет указанного свойства, метод вернёт `false`.

Примеры
-------

### Пример: базовое использование `propertyIsEnumerable`

Следующий пример показывает использование метода `propertyIsEnumerable` на объектах и массивах:

```js
var o = {};
var a = [];
o.prop = "перечисляемое";
a[0] = "перечисляемое";

o.propertyIsEnumerable("prop"); // вернёт true
a.propertyIsEnumerable(0); // вернёт true
```

### Пример: определённые пользователем и встроенные объекты

Следующий пример демонстрирует перечисляемость свойств, определённых пользователем и встроенных свойств:

```js
var a = ["перечисляемое"];

a.propertyIsEnumerable(0); // вернёт true
a.propertyIsEnumerable("length"); // вернёт false

Math.propertyIsEnumerable("random"); // вернёт false
this.propertyIsEnumerable("Math"); // вернёт false
```

### Пример: собственные и унаследованные свойства

```js
var a = [];
a.propertyIsEnumerable("constructor"); // вернёт false

function firstConstructor() {
  this.property = "не перечисляемое";
}

firstConstructor.prototype.firstMethod = function () {};

function secondConstructor() {
  this.method = function method() {
    return "перечисляемый";
  };
}

secondConstructor.prototype = new firstConstructor();
secondConstructor.prototype.constructor = secondConstructor;

var o = new secondConstructor();
o.arbitraryProperty = "перечисляемое";

o.propertyIsEnumerable("arbitraryProperty"); // вернёт true
o.propertyIsEnumerable("method"); // вернёт true
o.propertyIsEnumerable("property"); // вернёт false

o.property = "перечисляемое";

o.propertyIsEnumerable("property"); // вернёт true

// Эти вызовы вернут false, поскольку все свойства находятся в прототипе,
// который метод propertyIsEnumerable не просматривает (даже несмотря на то,
// что последние два свойства перечисляются через цикл for...in)
o.propertyIsEnumerable("prototype"); // вернёт false (в JS 1.8.1/FF3.6)
o.propertyIsEnumerable("constructor"); // вернёт false
o.propertyIsEnumerable("firstMethod"); // вернёт false
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.propertyisenumerable |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Перечисляемость и собственность свойств (en-US)
* `for...in`
* `Object.keys()`
* `Object.defineProperty()`


Object.values() - JavaScript

Object.values()
===============

Метод **`Object.values()`** возвращает массив значений перечисляемых свойств объекта в том же порядке что и цикл `for...in`. Разница между циклом и методом в том, что цикл перечисляет свойства и из цепочки прототипов.

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

Синтаксис
---------
```

Object.values(obj)
```

### Параметры

`obj`

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

### Возвращаемое значение

Массив содержащий значения перечисляемых свойств объекта.

Описание
--------

`Object.values()` возвращает массив, чьи элементы это значения перечисляемых свойств найденных в объекте. Порядок такой же как если пройтись по объекту циклом вручную.

Примеры
-------

```js
var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// Массив как объект
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// Массив как объект со случайным порядком ключей
// Когда мы используем нумерованные ключ, значения возвращаются в порядке возрастания
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// getFoo неперечисляемое свойство
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  },
);
my_obj.foo = "bar";
console.log(Object.values(my_obj)); // ['bar']

// Аргумент, не являющийся объектом, будет приведён к объекту
console.log(Object.values("foo")); // ['f', 'o', 'o']
```

Полифил
-------

Для добавления совместимости `Object.values` со старым окружением, которое не поддерживает нативно его, вы можете найти полифил здесь tc39/proposal-object-values-entries или в es-shims/Object.values репозитории.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.values |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* Перечисляемость и принадлежность свойств
* `Object.keys()`
* `Object.entries()`
Экспериментальная возможность
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`


Object.prototype.__defineGetter__() - JavaScript

Object.prototype.\_\_defineGetter\_\_()
=======================================

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

 **Устарело:** Эта возможность была удалена из веб-стандартов. Хотя некоторые браузеры по-прежнему могут поддерживать её, она находится в процессе удаления. Не используйте её ни в старых, ни в новых проектах. Страницы или веб-приложения, использующие её, могут в любой момент сломаться.

Сводка
------

Метод **`__defineGetter__()`** привязывает свойство объекта к функции, вызываемой каждый раз при поиске этого свойства.

Синтаксис
---------
```

obj.__defineGetter__(prop, func)
```

### Параметры

`prop`

Строка, содержащая имя свойства, привязываемого к заданной функции.

`func`

Функция, привязываемая к поиску указанного свойства.

Описание
--------

Метод `__defineGetter__()` позволяет определить геттер (en-US) на уже существующем объекте.

Примеры
-------

```js
// Нестандартный и устаревший способ

const o = {};
o.\_\_defineGetter\_\_("gimmeFive", function () {
  return 5;
});
console.log(o.gimmeFive); // 5

// Способы, совместимые со стандартом

// Использование оператора get
const o = {
  get gimmeFive() {
    return 5;
  },
};
console.log(o.gimmeFive); // 5

// Использование Object.defineProperty()
const o = {};
Object.defineProperty(o, "gimmeFive", {
  get: function () {
    return 5;
  },
});
console.log(o.gimmeFive); // 5
```

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

Не является частью какой-либо спецификации.

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.prototype.__defineSetter__()`
* оператор `get` (en-US)
* `Object.defineProperty()`
* `Object.prototype.__lookupGetter__()`
* `Object.prototype.__lookupSetter__()`
* Руководство по JS: определение геттеров и сеттеров
* [Запись в блоге] Устаревание \_\_defineGetter\_\_ и \_\_defineSetter\_\_ (англ.)
* Firefox bug 647423


Object.defineProperties() - JavaScript

Object.defineProperties()
=========================

Сводка
------

Метод **`Object.defineProperties()`** определяет новые или изменяет существующие свойства, непосредственно на объекте, возвращая этот объект.

Синтаксис
---------
```

Object.defineProperties(obj, props)
```

### Параметры

`obj`

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

`props`

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

`configurable`

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

`enumerable`

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

`value`

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

`writable`

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

`get`

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

`set`

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

### Возвращаемое значение

Объект, переданный в функцию.

Описание
--------

Метод `Object.defineProperties()`, по сути, определяет все свойства, соответствующие собственным свойствам объекта `props`, на объекте `obj`.

Примеры
-------

```js
Object.defineProperties(obj, {
  property1: {
    value: true,
    writable: true,
  },
  property2: {
    value: "Hello",
    writable: false,
  },
  // и т.д.
});
```

Полифил
-------

Предполагается, что среда выполнения осталась нетронутой, все имена и свойства ссылаются на свои изначальные значения. Оригинальный метод `Object.defineProperties` почти полностью эквивалентен (смотрите комментарий в функции `isCallable`) следующей реализации на JavaScript:

```js
function defineProperties(obj, properties) {
  function convertToDescriptor(desc) {
    function hasProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }

    function isCallable(v) {
      // NB: изменить при необходимости считать вызываемым что-то ещё, кроме функций.
      return typeof v === "function";
    }

    if (typeof desc !== "object" || desc === null) {
      throw new TypeError("bad desc");
    }

    var d = {};

    if (hasProperty(desc, "enumerable")) {
      d.enumerable = !!obj.enumerable;
    }
    if (hasProperty(desc, "configurable")) {
      d.configurable = !!obj.configurable;
    }
    if (hasProperty(desc, "value")) {
      d.value = obj.value;
    }
    if (hasProperty(desc, "writable")) {
      d.writable = !!desc.writable;
    }
    if (hasProperty(desc, "get")) {
      var g = desc.get;

      if (!isCallable(g) && g !== "undefined") {
        throw new TypeError("bad get");
      }
      d.get = g;
    }
    if (hasProperty(desc, "set")) {
      var s = desc.set;
      if (!isCallable(s) && s !== "undefined") {
        throw new TypeError("bad set");
      }
      d.set = s;
    }

    if (("get" in d || "set" in d) && ("value" in d || "writable" in d)) {
      throw new TypeError("identity-confused descriptor");
    }

    return d;
  }

  if (typeof obj !== "object" || obj === null) {
    throw new TypeError("bad obj");
  }

  properties = Object(properties);

  var keys = Object.keys(properties);
  var descs = [];

  for (var i = 0; i < keys.length; i++) {
    descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);
  }

  for (var i = 0; i < descs.length; i++) {
    Object.defineProperty(obj, descs[i][0], descs[i][1]);
  }

  return obj;
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.defineproperties |

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

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

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

* `Object.defineProperty()`
* `Object.keys()`
* Перечисляемость и собственность свойств (en-US)