Object.prototype.toLocaleString() - JavaScript

Object.prototype.toLocaleString()
=================================

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

Метод **`toLocaleString()`** возвращает строку, представляющую объект. Этот метод предназначен для переопределения унаследованными объектами в целях поддержки зависимости от локали.

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

obj.toLocaleString();
```

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

Метод `toLocaleString` объекта `Object` возвращает результат вызова метода `toString()`.

Эта функция обеспечивает объектам обобщённый метод `toLocaleString`, хотя и не все объекты могут её использовать. Смотрите ниже список таких объектов.

### Объекты, переопределяющие `toLocaleString`

* `Array`: `Array.prototype.toLocaleString()`
* `Number`: `Number.prototype.toLocaleString()`
* `Date`: `Date.prototype.toLocaleString()`
Спецификации
------------

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

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

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

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

* `Object.prototype.toString()`


Object.isExtensible() - JavaScript

Object.isExtensible()
=====================

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

Метод **`Object.isExtensible()`** определяет, является ли объект расширяемым (то есть, можно ли к нему добавлять новые свойства).

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

Object.isExtensible(obj)
```

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

`obj`

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

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

Объекты являются расширяемыми по умолчанию: к ним можно добавлять новые свойства и (в движках, поддерживающих свойство `Object.prototype.__proto__`) их можно изменять. Объект может быть помечен, как не изменяемый с помощью методов `Object.preventExtensions()`, `Object.seal()` или `Object.freeze()`.

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

```js
// Новые объекты являются расширяемыми.
var empty = {};
assert(Object.isExtensible(empty) === true);

// ...но это может быть изменено.
Object.preventExtensions(empty);
assert(Object.isExtensible(empty) === false);

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

// Замороженные объекты также по определению не расширяемы.
var frozen = Object.freeze({});
assert(Object.isExtensible(frozen) === false);
```

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

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

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

> Object.isExtensible(1)
false                         // код ES6
```

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

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

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

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

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

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


Object.seal() - JavaScript

Object.seal()
=============

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

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

Object.seal(obj)
```

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

`obj`

Запечатываемый объект.

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

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

Цепочка прототипов не затрагивается. Однако, свойство `Object.prototype.__proto__`
Устарело
 также запечатываться.

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

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

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

var o = Object.seal(obj);

assert(o === obj);
assert(Object.isSealed(obj) === true);

// Изменение значений свойств на запечатанном объекте всё ещё работает.
obj.foo = "quux";

// Но вы не можете преобразовать свойства данных в свойства доступа и наоборот.
Object.defineProperty(obj, "foo", {
  get: function () {
    return "g";
  },
}); // выбросит TypeError

// Теперь любые изменения, кроме изменения значений свойств, не будут работать.
obj.quaxxor = "дружелюбная утка"; // молча не добавит свойство
delete obj.foo; // молча не удалит свойство

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

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

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

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

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

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

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

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

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

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

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

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


Object.getOwnPropertyNames() - JavaScript

Object.getOwnPropertyNames()
============================

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

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

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

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

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

`obj`

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

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

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

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

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

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

### Пример: использование `Object.getOwnPropertyNames()`

```js
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // напечатает '0,1,2,length'

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

// Печать имён и значений свойств с помощью Array.forEach
Object.getOwnPropertyNames(obj).forEach(function (val, idx, array) {
  console.log(val + " -> " + obj[val]);
});
// напечатает
// 0 -> a
// 1 -> b
// 2 -> c

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

console.log(Object.getOwnPropertyNames(my_obj).sort()); // напечатает 'foo,getFoo'
```

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

Элементы в цепочке прототипов не перечисляются:

```js
function ParentClass() {}
ParentClass.prototype.inheritedMethod = function () {};

function ChildClass() {
  this.prop = 5;
  this.method = function () {};
}
ChildClass.prototype = new ParentClass();
ChildClass.prototype.prototypeMethod = function () {};

alert(
  Object.getOwnPropertyNames(
    new ChildClass(), // ['prop', 'method']
  ),
);
```

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

Здесь используется функция `Array.prototype.filter()` для удаления перечисляемых ключей (полученных через метод `Object.keys()`) из списка всех ключей (полученных через метод `Object.getOwnPropertyNames()`) и, таким образом, оставляющая только неперечисляемые ключи.

```js
var target = myObject;
var enum_and_nonenum = Object.getOwnPropertyNames(target);
var enum_only = Object.keys(target);
var nonenum_only = enum_and_nonenum.filter(function (key) {
  var indexInEnum = enum_only.indexOf(key);
  if (indexInEnum == -1) {
    // если ключ не найден в массиве enum\_only, значит ключ является не перечисляемым
    // и нужно вернуть true, чтобы он попал в результирующий массив
    return true;
  } else {
    return false;
  }
});

console.log(nonenum_only);
```

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

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

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

> Object.getOwnPropertyNames('foo')
['length', '0', '1', '2']         // код ES6
```

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

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

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

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

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

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


Object.prototype.valueOf() - JavaScript

Object.prototype.valueOf()
==========================

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

Метод **`valueOf()`** возвращает примитивное значение указанного объекта.

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

object.valueOf()
```

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

JavaScript вызывает метод `valueOf` для преобразования объекта в примитивное значение. Вам редко потребуется вызывать метод `valueOf` самостоятельно; JavaScript автоматически вызывает его при обнаружении объекта, когда ожидается примитивное значение.

По умолчанию, метод `valueOf` наследуется каждым объектом, произошедшим от `Object`. Каждый встроенный объект ядра переопределяет этот метод, возвращая подходящее значение. Если объект не имеет примитивного значения, `valueOf` возвращает сам объект, который отображается как:

```js
[object Object]
```

Вы можете использовать `valueOf` в своём коде для преобразования встроенных объектов в примитивное значение. Когда вы создаёте пользовательский объект, вы можете переопределить метод `Object.prototype.valueOf()`, чтобы вызывать собственный метод вместо метода по умолчанию из `Object`.

### Переопределение `valueOf` в пользовательских объектах

Вы можете создать функцию, вызываемую вместо метода `valueOf` по умолчанию. Ваша функция не должна принимать аргументов.

Предположим, у вас есть объект типа `myNumberType` и вы хотите создать для него метод `valueOf`. Следующий код присваивает определённую пользователем функцию методу `valueOf` объекта:

```js
myNumberType.prototype.valueOf = function () {
  return customPrimitiveValue;
};
```

Начиная с этого места в вашем коде, в любое время, когда объект типа `myNumberType` будет использоваться в контексте, где он должен быть представлен примитивным значением, JavaScript будет автоматически вызывать функцию, определённую в этом коде.

Метод объекта `valueOf` обычно вызывается движком JavaScript, но вы можете вызвать его и самостоятельно, как показано ниже:

```js
myNumber.valueOf();
```

**Примечание:** объекты в строковом контексте преобразуются с помощью метода `toString()`, что отличается от объектов `String`, преобразующихся в строковые примитивы методом `valueOf`. Все объекты имеют преобразование в строку вида "`[object type]`". Но многие объекты не преобразуются в число, логическое значение или функцию.

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

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

```js
var o = new Object();
myVar = o.valueOf(); // [object Object]
```

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

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

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

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

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

* `Object.prototype.toString()`
* `parseInt()`


Object.prototype.__proto__ - JavaScript

Object.prototype.\_\_proto\_\_
==============================

**Предупреждение:** Изменение прототипа `[[Prototype]]` объекта является, по самой природе оптимизации доступа к свойствам в современных движках JavaScript, очень медленной операцией, это справедливо для ***любого*** браузера и движка JavaScript. Изменение прототипов очень тонко и обширно влияет на производительность, причём это влияние не ограничивается просто временем для операции присваивания `obj.__proto__ = ...`, оно может распространяться на ***любой*** код, который имеет доступ к ***любому*** объекту, чей прототип `[[Prototype]]` был изменён. Если вы заботитесь о производительности, вы никогда не должны изменять прототип `[[Prototype]]` объекта. Вместо этого создайте объект с нужным прототипом `[[Prototype]]`, с помощью метода `Object.create()`.

**Предупреждение:** хотя на сегодняшний момент большинство браузеров поддерживают свойство `Object.prototype.__proto__`, его поведение только недавно было стандартизировано в новой спецификации ECMAScript 6. Если вам требуется поддержка браузеров до этой спецификации, рекомендуется использовать вместо него метод `Object.getPrototypeOf()`.

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

Свойство `__proto__` объекта `Object.prototype` (en-US) является свойством доступа (комбинацией геттера и сеттера), которое расширяет внутренний прототип `[[Prototype]]` объекта (являющийся объектом или `null`), через который осуществлялся доступ.

Использование свойства `__proto__` вызывает споры и многих оно разочаровало. Ранее оно никогда не включалось в спецификацию EcmaScript, но современные браузеры всё равно решили его реализовать. Сегодня свойство `__proto__` стандартизировано в спецификации ECMAScript 6 и будет поддерживаться в будущем. Тем не менее, изменение прототипа `[[Prototype]]` объекта всё ещё остаётся медленной операцией, которую следует избегать, если вы беспокоитесь о производительности.

Свойство `__proto__` также может использоваться при определении литерала объекта, устанавливая прототип `[[Prototype]]` объекта при его создании. Этот способ может рассматриваться как альтернатива методу `Object.create()`. Смотрите также литеральный синтаксис инициализации объекта.

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

```js
var shape = {},
  circle = new Circle();

// Установка прототипа объекта
shape.__proto__ = circle;
// Получение прототипа объекта
console.log(shape.__proto__ === circle); // true
```

Обратите внимание: название свойства состоит из двух подчёркиваний, следующих за ними пяти символов «proto» и следующих за ними ещё двух подчёркиваний.

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

Геттер свойства `__proto__` расширяет значение внутреннего прототипа `[[Prototype]]` объекта. Для объектов, созданных с использованием литеральной формы создания объекта, это значение равно `Object.prototype` (en-US). Для функций это значение равно `Function.prototype` (en-US). Для объектов, созданных с использованием формы `new fun`, где `fun` является одной из встроенных функций-конструкторов, предоставляемых JavaScript (`Array`, `Boolean`, `Date`, `Number`, `Object`, `String` и так далее — включая новые конструкторы, добавленные в процессе развития JavaScript), это значение равно `fun.prototype`. Для объектов, созданных с использованием формы `new fun`, где `fun` является функцией, определённой в скрипте, это значение равно значению `fun.prototype` во время вычисления `new fun`. Именно поэтому при присваивании `fun.prototype` нового значения, ранее созданные экземпляры `fun` продолжат использовать предыдущее значение в качестве своего прототипа `[[Prototype]]`, а последующие вызовы `new fun` будут использовать вновь присвоенное значение в качестве своего прототипа `[[Prototype]]`.

Геттер `__proto__` позволяет прототипу `[[Prototype]]` объекта быть изменяемым. Объект должен быть расширяемым в соответствии с `Object.isExtensible()`: если это не так, выкидывается исключение `TypeError`. Предоставляемое значение должно быть объектом или `null`. Предоставление любого другого значения ничего не даст.

Для понимания того, как прототипы используются для наследования, смотрите статью руководства «Наследование и цепочки прототипов».

Свойство `__proto__` является простым свойством доступа на объекте `Object.prototype` (en-US) — свойством, состоящим из геттера и сеттера. Свойство `__proto__` будет найдено, если, в конечном итоге, его поиск пройдёт через `Object.prototype` (en-US), но при доступе к нему не через `Object.prototype` (en-US), оно найдено не будет. Если перед просмотром `Object.prototype` (en-US) буден найдено какое-нибудь другое свойство `__proto__`, оно скроет искомое свойство `Object.prototype` (en-US).

```js
var noProto = Object.create(null);

console.log(typeof noProto.__proto__); // undefined
console.log(Object.getPrototypeOf(noProto)); // null

noProto.__proto__ = 17;

console.log(noProto.__proto__); // 17
console.log(Object.getPrototypeOf(noProto)); // null

var protoHidden = {};
Object.defineProperty(protoHidden, "\_\_proto\_\_", {
  value: 42,
  writable: true,
  configurable: true,
  enumerable: true,
});

console.log(protoHidden.__proto__); // 42
console.log(Object.getPrototypeOf(protoHidden) === Object.prototype); // true
```

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

В следующем примере создаётся новый экземпляр `Employee`, а затем проверяется, что его свойство `__proto__` является тем же самым объектом, что и его конструктор `prototype`.

```js
// Декларируем функцию, используемую как конструктор
function Employee() {
  /\* инициализируем экземпляр \*/
}

// Создаём новый экземпляр Employee
var fred = new Employee();

// Проверка на эквивалентность
fred.__proto__ === Employee.prototype; // true
```

В этот момент `fred` унаследован от `Employee`, однако присваивание другого объекта в `fred.__proto__` может изменить это:

```js
function Cow() {
  /\* инициализируем экземпляр \*/
}

// Присваиваем \_\_proto\_\_ новый объект
fred.__proto__ = Cow.prototype;
```

Теперь `fred` наследуется непосредственно от `Cow.prototype`, а не от `Employee.prototype`, и теряет свойства, изначально унаследованные от `Employee.prototype`.

Однако, это применяется только к расширяемым объектам, у нерасширяемых объектов свойство `__proto__` не может быть изменено:

```js
var obj = {};
Object.preventExtensions(obj);

obj.__proto__ = {}; // выкинет TypeError
```

Обратите внимание, что свойство `__proto__` может быть переопределено даже у объекта `Object.prototype`, если новая цепочка заканчивается `null`:

```js
var b = {};

Object.prototype.__proto__ = Object.create(
  null, // [[Prototype]]
  {
    hi: {
      value: function () {
        alert("hi");
      },
    },
  },
);

b.hi();
```

Если свойство `__proto__` объекта `Object.prototype` (en-US) не установлено в `null`, или в другой объект, чья цепочка прототипов, в конечном итоге, явно не заканчивается значением `null`, будет выкинуто исключение `TypeError` «циклическое значение \_\_proto\_\_», поскольку цепочка должна заканчиваться `null` (как это и происходит на `Object.prototype` (en-US) при нормальных обстоятельствах).

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_proto\_\_ |

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

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

**Примечание:** спецификация ES6 требует поддержку свойства `__proto__` только в браузерах и не требует его поддержку в других окружениях (хотя оно и рекомендуется в качестве обязательного). Если ваш код должен работать в не-браузерных окружениях, вместо свойства рекомендуется использовать методы `Object.getPrototypeOf()` и `Object.setPrototypeOf()`.

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

* `Object.prototype.isPrototypeOf()`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()`


Object.entries() - JavaScript

Object.entries()
================

**`Object.entries()`** метод возвращает массив собственных перечисляемых свойств указанного объекта в формате `[key, value]`, в том же порядке, что и в цикле `for...in` (разница в том, что for-in перечисляет свойства из цепочки прототипов). Порядок элементов в массиве который возвращается **`Object.entries()`** не зависит от того как объект объявлен. Если существует необходимость в определённом порядке, то массив должен быть отсортирован до вызова метода, например `Object.entries(obj).sort((a, b) => a[0] - b[0]);`.

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

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

Object.entries(obj)
```

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

`obj`

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

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

Массив перечислений собственных свойств объекта с парами `[key, value]`.

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

`Object.entries()` возвращает массив, элементами которого являются массивы, соответствующие перечисляемому свойству пары `[key, value],` найденной прямо в `object`. Порядок свойств тот же, что и при прохождении циклом по свойствам объекта вручную.

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

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

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

// массив как объект c random сортировкой ключей
var an_obj = { 100: "a", 2: "b", 7: "c" };
console.log(Object.entries(an_obj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
var my_obj = Object.create(
  {},
  {
    getFoo: {
      value: function () {
        return this.foo;
      },
    },
  },
);
my_obj.foo = "bar";
console.log(Object.entries(my_obj)); // [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries("foo")); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
```

```
// returns an empty array for any primitive type, since primitives have no own properties
console.log(Object.entries(100)); // [ ]

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
```

### Преобразование `Object` в `Map`

Конструктор `new Map()` (en-US) принимает повторение *значений*. С `Object.entries` вы легко можете преобразовать `Object` в `Map` (en-US):

```js
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
```

### Итерация по `Object`

Используя метод Разбора Массивов Вы можете легко итерировать объекты.
```

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj).forEach(([key, value]) => console.log(`${key}: ${value}`)); // "foo: bar", "baz: 42"
```

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

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

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

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

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

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

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

* Enumerability and ownership of properties
* `Object.keys()`
* `Object.values()`
Экспериментальная возможность
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`


Object.getOwnPropertyDescriptors() - JavaScript

Object.getOwnPropertyDescriptors()
==================================

Метод **`Object.getOwnPropertyDescriptors()`** возвращает все собственные дескрипторы свойств данного объекта.

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

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

Object.getOwnPropertyDescriptors(obj)
```

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

`obj`

Объект, для которого нужно получить все собственные дескрипторы свойств.

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

Объект, содержащий все собственные дескрипторы свойств объекта. Может быть пустой объект, если нет свойств.

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

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

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

`value`

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

**`writable`**

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

`get`

Функция, которая служит в качестве получателя для свойства, или `undefined` если нет получателя (только дескрипторы доступа).

`set`

Функция, которая служит установщиком для свойства, или `undefined` если установщика нет (только дескрипторы доступа).

`configurable`

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

`enumerable`

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

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

### Создание поверхностного клона

В то время как метод `Object.assign()` будет только копировать перечисляемые и собственные свойства из исходного объекта в целевой объект, вы можете использовать этот метод и `Object.create()` для поверхностного копирования между двумя неизвестными объектами:

```js
Object.create(
  Object.getPrototypeOf(obj),
  Object.getOwnPropertyDescriptors(obj),
);
```

### Создание подкласса

Типичный способ создания подкласса это определить подкласс, определить свойства этого экземпляра. Это может быть неудобно особенно для получателей и установщиков. Вместо этого, вы можете использовать этот код для установки прототипа:

```js
function superclass() {}
superclass.prototype = {
  // Определите ваши методы и свойства здесь
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, {
  // Определите ваши методы и свойства здесь
});
```

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

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

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

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

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

* `Object.getOwnPropertyDescriptor()`
* `Object.defineProperty()`
* Polyfill


Object.prototype.constructor - JavaScript

Object.prototype.constructor
============================

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

Возвращает ссылку на функцию `Object`, создавшую прототип экземпляра. Обратите внимание, что значение этого свойства является ссылкой на саму функцию, а не строкой, содержащей имя функции. Для примитивных значений, вроде `1`, `true` или `"test"`, значение доступно только для чтения.

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

Все объекты наследуют свойство `constructor` из своего прототипа:

```js
var o = {};
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var n = new Number(3);
n.constructor === Number; // true
```

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

### Пример: отображение конструктора объекта

В следующем примере создаётся прототип `Tree` и объект этого типа `theTree`. Затем в примере отображается свойство `constructor` объекта `theTree`.

```js
function Tree(name) {
  this.name = name;
}

var theTree = new Tree("Красное дерево");
console.log("theTree.constructor равен " + theTree.constructor);
```

Вывод примера будет следующим:

```js
theTree.constructor равен function Tree(name) {
  this.name = name;
}
```

### Пример: изменение конструктора объекта

Следующий пример показывает, как изменить конструктор значений общих объектов. Не затрагиваются только значения `true`, `1` и `"тест"`, поскольку они имеют родные конструкторы только для чтения. Этот пример показывает, что полагаться на свойство `constructor` объекта не всегда безопасно.

```js
function Type() {}

var types = [
  new Array(),
  [],
  new Boolean(),
  true, // останется неизменным
  new Date(),
  new Error(),
  new Function(),
  function () {},
  Math,
  new Number(),
  1, // останется неизменным
  new Object(),
  {},
  new RegExp(),
  /(?:)/,
  new String(),
  "тест", // останется неизменным
];

for (var i = 0; i < types.length; i++) {
  types[i].constructor = Type;
  types[i] = [
    types[i].constructor,
    types[i] instanceof Type,
    types[i].toString(),
  ];
}

console.log(types.join("\n"));
```

Вывод примера будет следующим:

```js
function Type() {},false,
function Type() {},false,
function Type() {},false,false
function Boolean() {
    [native code]
},false,true
function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600
function Type() {},false,Error
function Type() {},false,function anonymous() {

}
function Type() {},false,function () {}
function Type() {},false,[object Math]
function Type() {},false,0
function Number() {
    [native code]
},false,1
function Type() {},false,[object Object]
function Type() {},false,[object Object]
function Type() {},false,/(?:)/
function Type() {},false,/(?:)/
function Type() {},false,
function String() {
    [native code]
},false,тест
```

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

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

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

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


Object.prototype.__lookupGetter__() - JavaScript

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

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

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

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

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

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

obj.__lookupGetter__(sprop)
```

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

`sprop`

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

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

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

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

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

```js
var obj = {
  get foo() {
    return Math.random() > 0.5 ? "foo" : "bar";
  },
};

// Нестандартный и устаревший способ
obj.\_\_lookupGetter\_\_("foo");
// (function() { return Math.random() > 0.5 ? 'foo' : 'bar'; })

// Способ, совместимый со стандартом
Object.getOwnPropertyDescriptor(obj, "foo").get;
// (function() { return Math.random() > 0.5 ? 'foo' : 'bar'; })
```

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

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

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

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

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

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


Object.setPrototypeOf() - JavaScript

Object.setPrototypeOf()
=======================

**Предупреждение:** Изменение прототипа `[[Prototype]]` объекта является, по самой природе оптимизации доступа к свойствам в современных движках JavaScript, очень медленной операцией, это справедливо для ***любого*** браузера и движка JavaScript. Изменение прототипов очень тонко и обширно влияет на производительность, причём это влияние не ограничивается просто временем, проведённым внутри метода `Object.setPrototypeOf()`, оно может распространяться на ***любой*** код, который имеет доступ к ***любому*** объекту, чей прототип `[[Prototype]]` был изменён. Если вы заботитесь о производительности, вы никогда не должны изменять прототип `[[Prototype]]` объекта. Вместо этого создайте объект с нужным прототипом `[[Prototype]]`, с помощью метода `Object.create()`.

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

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

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

Object.setPrototypeOf(obj, prototype);
```

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

`obj`

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

`prototype`

Новый прототип объекта (объект или `null`).

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

Выкидывает исключение `TypeError`, если объект, чей прототип `[[Prototype]]` является не расширяемым, согласно методу `Object.isExtensible()`. Не делает ничего, если параметр `prototype` не является объектом или значением `null` (то есть, является числом, строкой, логическим значением или `undefined`). В противном случае метод устанавливает прототип `[[Prototype]]` объекта `obj` в новое значение.

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

```js
var dict = Object.setPrototypeOf({}, null);
```

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

Используя старое свойство `Object.prototype.__proto__`, мы можем легко определить `Object.setPrototypeOf()`, если он ещё не доступен:

```js
if (!Object.setPrototypeOf) {
  Object.prototype.setPrototypeOf = function (obj, proto) {
    if (obj.__proto__) {
      obj.__proto__ = proto;
      return obj;
    } else {
      // Если нужно будет определить прототип у Object.create(null) объекта
      var Fn = function () {
        for (var key in obj) {
          //Если в объект уже были определены некоторые свойства
          Object.defineProperty(this, key, {
            value: obj[key],
          });
        }
      };
      Fn.prototype = proto;
      return new Fn();
    }
  };
}
```

Добавление цепочки прототипов
-----------------------------

Сочетание метода `Object.getPrototypeOf()` и свойства `Object.prototype.__proto__` позволяет добавить целую цепочку прототипов к новому прототипу объекта:

```js
/\*\*
 \*\*\* Object.appendChain(@object, @prototype)
 \*
 \* Присоединяет первый неродной прототип цепочки к новому прототипу.
 \* Возвращает @object (если он был примитивным значением, оно будет преобразовано в объект).
 \*
 \*\*\* Object.appendChain(@object [, "@arg\_name\_1", "@arg\_name\_2", "@arg\_name\_3", "..."], "@function\_body")
 \*\*\* Object.appendChain(@object [, "@arg\_name\_1, @arg\_name\_2, @arg\_name\_3, ..."], "@function\_body")
 \*
 \* Присоединяет первый не родной прототип цепочки к родному объекту Function.prototype, затем присоединяет
 \* new Function(["@arg"(s)], "@function\_body") к этой цепочке.
 \* Возвращает функцию.
 \*
 \*\*/

Object.appendChain = function (oChain, oProto) {
  if (arguments.length < 2) {
    throw new TypeError("Object.appendChain - Not enough arguments");
  }
  if (typeof oProto === "number" || typeof oProto === "boolean") {
    throw new TypeError(
      "second argument to Object.appendChain must be an object or a string",
    );
  }

  var oNewProto = oProto,
    oReturn =
      (o2nd =
      oLast =
        oChain instanceof this ? oChain : new oChain.constructor(oChain));

  for (
    var o1st = this.getPrototypeOf(o2nd);
    o1st !== Object.prototype && o1st !== Function.prototype;
    o1st = this.getPrototypeOf(o2nd)
  ) {
    o2nd = o1st;
  }

  if (oProto.constructor === String) {
    oNewProto = Function.prototype;
    oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
    this.setPrototypeOf(oReturn, oLast);
  }

  this.setPrototypeOf(o2nd, oNewProto);
  return oReturn;
};
```

### Использование

#### Первый пример: присоединение цепочки к прототипу

```js
function Mammal() {
  this.isMammal = "да";
}

function MammalSpecies(sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies("Felis");

alert(oCat.isMammal); // 'да'

function Animal() {
  this.breathing = "да";
}

Object.appendChain(oCat, new Animal());

alert(oCat.breathing); // 'да'
```

#### Второй пример: преобразование примитивного значения в экземпляр его конструктора и присоединение его цепочки к прототипу

```js
function Symbol() {
  this.isSymbol = "да";
}

var nPrime = 17;

alert(typeof nPrime); // 'number'

var oPrime = Object.appendChain(nPrime, new Symbol());

alert(oPrime); // '17'
alert(oPrime.isSymbol); // 'да'
alert(typeof oPrime); // 'object'
```

#### Третий пример: присоединение цепочки к объекту `Function.prototype` и новой функции к этой цепочке

```js
function Person(sName) {
  this.identity = sName;
}

var george = Object.appendChain(
  new Person("Георг"),
  'alert("Привет, парни!!");',
);

alert(george.identity); // 'Георг'
george(); // 'Привет, парни!!'
```

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

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

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

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

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

* `Object.prototype.isPrototypeOf()`
* `Object.getPrototypeOf()`
* `Object.prototype.__proto__`


Object.preventExtensions() - JavaScript

Object.preventExtensions()
==========================

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

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

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

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

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

`obj`

Объект, который нужно сделать нерасширяемым.

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

Объект, который делается нерасширяемым.

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

Объект называется расширяемым, если к нему могут быть добавлены новые свойства. `Object.preventExtensions()` помечает объект как нерасширяемый, так что он никогда не будет иметь других свойств, кроме тех, что были у него на момент пометки его нерасширяемым. Обратите внимание, что, в общем случае, свойства нерасширяемого объекта всё ещё могут быть *удалены*. Попытка добавить новые свойства к нерасширяемому объекту потерпит неудачу, либо молча, либо с выбрасыванием исключения `TypeError` (как правило, но не обязательно, это происходит в строгом режиме (en-US)).

Метод `Object.preventExtensions()` предотвращает добавление только собственных свойств. Свойства всё ещё могут быть добавлены в прототип объекта. Однако, вызов `Object.preventExtensions()` на объекте также предотвращает расширение его свойства `Object.prototype.__proto__`
Устарело
.

Если превратить расширяемый объект в нерасширяемый возможно, в ECMAScript 5 нет никакого способа сделать обратную операцию.

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

```js
// Object.preventExtensions возвращает объект, который нужно сделать нерасширяемым.
var obj = {};
var obj2 = Object.preventExtensions(obj);
assert(obj === obj2);

// Объекты по умолчанию являются расширяемыми.
var empty = {};
assert(Object.isExtensible(empty) === true);

// ...но это может быть изменено.
Object.preventExtensions(empty);
assert(Object.isExtensible(empty) === false);

// Object.defineProperty выбрасывает исключение при добавлении нового свойства в нерасширяемый объект.
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // выбросит TypeError

// В строгом режиме, попытки добавить новые свойства к нерасширяемому объекту, будут выбрасывать исключение TypeError.
function fail() {
  "use strict";
  nonExtensible.newProperty = "ОШИБКА"; // выбросит TypeError
}
fail();

// РАСШИРЕНИЕ (работает только в движках, поддерживающих свойство \_\_proto\_\_
// (которое является устаревшим. Используйте вместо него метод Object.getPrototypeOf)):
// нерасширяемые объекты неизменны.
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // выбросит TypeError
```

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

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

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

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

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

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

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

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

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

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


Object.fromEntries() - JavaScript

Object.fromEntries()
====================

Метод **`Object.fromEntries()`** преобразует список пар ключ-значение в объект.

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

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

Object.fromEntries(iterable);
```

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

`iterable`

Итерируемый объект, такой как `Array` или `Map` (en-US) или другие объекты, реализующие iterable протокол.

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

Новый объект, свойства которого задаются записями iterable.

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

Метод `Object.fromEntries()` принимает список пар ключ-значение и возвращает новый объект, свойства которого задаются этими записями. Ожидается, что аргумент *iterable* будет объектом, который реализует метод `@@iterator`, который возвращает объект итератора, который создаёт двухэлементный массивоподобный объект, первый элемент которого является значением, которое будет использоваться в качестве ключа свойства, а второй элемент — значением связанного с этим ключом свойства.

`Object.fromEntries()` выполняет процедуру, обратную `Object.entries()`.

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

### Преобразование `Map` в `Object`

С `Object.fromEntries` вы можете преобразовать `Map` (en-US) в `Object`:

```js
const map = new Map([
  ["foo", "bar"],
  ["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
```

### Преобразование `Array` в `Object`

С `Object.fromEntries` вы можете преобразовать `Array` в `Object`:

```js
const arr = [
  ["0", "a"],
  ["1", "b"],
  ["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
```

### Трансформации объектов

С `Object.fromEntries`, обратным ему методом `Object.entries()` и методами манипулирования массивами вы можете преобразовывать объекты следующим образом:

```js
const object1 = { a: 1, b: 2, c: 3 };

const object2 = Object.fromEntries(
  Object.entries(object1).map(([key, val]) => [key, val \* 2]),
);

console.log(object2);
// { a: 2, b: 4, c: 6 }
```

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

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

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

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

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

* `Object.entries()`
* `Object.keys()`
* `Object.values()`
* `Map.prototype.entries()` (en-US)
* `Map.prototype.keys()` (en-US)
* `Map.prototype.values()` (en-US)


Function.prototype.apply() - JavaScript

Function.prototype.apply()
==========================

Общие сведения
--------------

Метод **`apply()`** вызывает функцию с указанным значением `this` и аргументами, предоставленными в виде массива (либо массивоподобного объекта (en-US)).

**Примечание:** хотя синтаксис этой функции практически полностью идентичен функции `call()`, фундаментальное различие между ними заключается в том, что функция `call()` принимает список аргументов, в то время как функция `apply()` принимает единичный массив аргументов.

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

fun.apply(thisArg, [argsArray])
```

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

`thisArg`

Значение `this`, предоставляемое для вызова функции *`fun`*. Обратите внимание, что `this` может не быть реальным значением, видимым этим методом: если метод является функцией в нестрогом режиме (en-US), значения `null` и `undefined` будут заменены глобальным объектом, а примитивные значения будут упакованы в объекты.

`argsArray` Необязательный

Массивоподобный объект, определяющий аргументы, с которыми функция *`fun`* должна быть вызвана, либо `null` или `undefined`, если в функцию не надо передавать аргументы. Начиная с ECMAScript 5 эти аргументы могут быть обобщёнными массивоподобными объектами, а не только массивом. Смотрите ниже информацию по совместимости с браузерами.

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

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

Метод `apply` очень похож на метод `call()`, за исключением поддерживаемого типа аргументов. Вы можете использовать массив аргументов вместо набора именованных параметров. Вместе с `apply` вы можете использовать литерал массива, например, `fun.apply(this, ['есть', 'бананы'])`, либо объект `Array`, например, `fun.apply(this, new Array('есть', 'бананы'))`.

Также вы можете использовать в качестве параметра `argsArray` псевдомассив `arguments` (en-US). `arguments` является локальной переменной функции. Он может использоваться для всех неопределённых аргументов вызываемого объекта. Таким образом, вы не обязаны знать, сколько и какие аргументы требует вызываемый объект при использовании метода `apply()`. Вы можете использовать псевдомассив `arguments` для передачи всех аргументов в вызываемый объект. Вызываемый объект самостоятельно разберётся с обработкой аргументов.

Начиная с 5-го издания ECMAScript, вы также можете использовать любой вид массивоподобного объекта, что на практике означает, что он должен иметь свойство `length` и целочисленные свойства в диапазоне `(0...length)`. В качестве примера, теперь вы можете использовать `NodeList` или свой собственный объект вида `{ 'length': 2, '0': 'есть', '1': 'бананы' }`.

**Примечание:** Большинство браузеров, включая Chrome 14 и Internet Explorer 9, всё ещё не принимают массивоподобные объекты и будут выбрасывать исключение.

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

### Пример: использование `apply()` для связи конструкторов объекта в цепочку

Вы можете использовать метод `apply()` для объединения в цепочку конструкторов объекта, как в Java. В следующем примере мы создадим в объекте `Function` глобальный метод `construct()`, который позволит нам использовать массивоподобные объекты с конструктором вместо списка аргументов.

```js
Function.prototype.construct = function (aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};
```

**Примечание:** метод `Object.create()`, использованный в этом примере, относительно новый. В качестве альтернативного способа можно рассмотреть возможность использования замыкания:

```js
Function.prototype.construct = function (aArgs) {
  var fConstructor = this,
    fNewConstr = function () {
      fConstructor.apply(this, aArgs);
    };
  fNewConstr.prototype = fConstructor.prototype;
  return new fNewConstr();
};
```

Пример использования:

```js
function MyConstructor() {
  for (var nProp = 0; nProp < arguments.length; nProp++) {
    this["property" + nProp] = arguments[nProp];
  }
}

var myArray = [4, "Привет, мир!", false];
var myInstance = MyConstructor.construct(myArray);

alert(myInstance.property1); // выведет 'Привет, мир!'
alert(myInstance instanceof MyConstructor); // выведет 'true'
alert(myInstance.constructor); // выведет 'MyConstructor'
```

**Примечание:** этот неродной метод `Function.construct()` не будет работать с некоторыми родными конструкторами (вроде конструктора `Date`, к примеру). В этих случаях вы можете использовать метод `Function.prototype.bind()` (например, представьте, что вы имеете следующий массив, который можно использовать с конструктором `Date`: `[2012, 11, 4]`; в этом случае вы напишите что-то вроде: `new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))()` — так или иначе, это не самый изящный способ и, вероятно, его не стоит использовать в рабочем окружении).

### Пример: использование `apply()` и встроенных функций

Умное использование метода `apply()` позволяет вам использовать встроенные функции для некоторых задач, для которых в противном случае пришлось бы писать цикл по массиву значений. В качестве примера давайте используем `Math.max()`/`Math.min()` для нахождения максимального/минимального значения в массиве.

```js
/\* мин/макс числа в массиве \*/
var numbers = [5, 6, 2, 3, 7];

/\* используем apply к Math.min/Math.max \*/
var max = Math.max.apply(
  null,
  numbers,
); /\* Это эквивалентно Math.max(numbers[0], ...)
 или Math.max(5, 6, ...) \*/
var min = Math.min.apply(null, numbers);

/\* сравним с простым алгоритмом с циклом \*/
(max = -Infinity), (min = +Infinity);

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max) {
    max = numbers[i];
  }
  if (numbers[i] < min) {
    min = numbers[i];
  }
}
```

Но будьте осторожны: при использовании метода `apply()` таким образом вы рискуете выйти за пределы ограничения на количество аргументов в движке JavaScript. Последствия применения функции с очень большим количеством аргументов (думается, больше десяти тысяч аргументов) различаются от движка к движку (JavaScriptCore имеет жёстко зашитое ограничение на количество аргументов в 65536), поскольку этот предел (на самом деле, это природа поведения любого чрезвычайно огромного стека) не определён. Некоторые движки будут выкидывать исключение. Хуже того, другие просто отбрасывают реально переданные функции аргументы сверх лимита. (Для иллюстрации последнего случая: если такой движок имеет ограничение в четыре элемента [реальное ограничение, конечно же, гораздо выше], это выглядело бы так, как если бы в примере выше в метод `apply()` были переданы аргументы `5, 6, 2, 3`, а не весь массив.) Если ваш массив значений может вырасти до десятков тысяч, используйте смешанный подход: применяйте вашу функцию к порциям массива:

```js
function minOfArray(arr) {
  var min = Infinity;
  var QUANTUM = 32768;

  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
    var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
    min = Math.min(submin, min);
  }

  return min;
}

var min = minOfArray([5, 6, 2, 3, 7]);
```

### Пример: использование `apply()` в «monkey-патчинге»

Метод `apply()` может быть лучшим вариантом для «monkey-патчинга» встроенных в Firefox функций, либо JS библиотек. Пусть у вас есть функция `someobject.foo()`, вы можете изменить её таким немного хакерским способом:

```js
var originalfoo = someobject.foo;
someobject.foo = function () {
  // Делаем что-то до вызова функции
  console.log(arguments);
  // Вызываем функцию так, как будто бы она была вызвана обычным образом:
  originalfoo.apply(this, arguments);
  // Делаем что-то после вызова функции.
};
```

Этот метод особенно удобен, когда вам нужно отладить события, либо интерфейс с чем-то, что не имеет API, вроде различных событий `.on([event]...`, например, тех что используются в Инспекторе инструментов разработчика).

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function.prototype.apply |

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

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

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

* объект `arguments` (en-US)
* `Function.prototype.bind()`
* `Function.prototype.call()`
* Функции и их область видимости (en-US)


Function.arguments - JavaScript

Function.arguments
==================

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

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

Свойство **`function.arguments`** ссылалось на массивоподобный объект, соответствующий аргументам, переданным в функцию. Используйте вместо него простую переменную `arguments` (en-US).

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

Синтаксис `function.arguments` устарел. Рекомендуемым способом доступа к объекту `arguments` (en-US), доступному внутри функций, является простая ссылка на переменную `arguments` (en-US).

В случае рекурсии, то есть, если функция `f` несколько раз появляется в стеке вызовов, значение `f.arguments` представляет аргументы, соответствующие самому последнему вызову функции.

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

```js
function f(n) {
  g(n - 1);
}

function g(n) {
  console.log("до: " + g.arguments[0]);
  if (n > 0) {
    f(n);
  }
  console.log("после: " + g.arguments[0]);
}

f(2);

// Вывод

// до: 1
// до: 0
// после: 0
// после: 1
```

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

#### No specification found

No specification data found for `javascript.builtins.Function.arguments`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

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

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

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

* объект `arguments` (en-US)
* Функции и их область видимости (en-US)


Function.displayName - JavaScript

Function.displayName
====================

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

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

Свойство **`function.displayName`** возвращает отображаемое имя функции.

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

Если оно определено, свойство `displayName` возвращает отображаемое имя функции:

```js
function doSomething() {}

alert(doSomething.displayName); // "undefined"

var popup = function (content) {
  alert(content);
};

popup.displayName = "Показать всплывающее окно";

alert(popup.displayName); // "Показать всплывающее окно"
```

Вы можете определить функцию с отображаемым именем в выражении функции (en-US):

```js
var object = {
  someMethod: function () {},
};

object.someMethod.displayName = "someMethod";

alert(object.someMethod.displayName); // выведет "someMethod"

try {
  someMethod;
} catch (e) {
  alert(e);
}
// ReferenceError: someMethod is not defined
```

Вы можете динамически изменять свойство `displayName` функции:

```js
var object = {
  // анонимная функция
  someMethod: function (value) {
    this.displayName = "someMethod (" + value + ")";
  },
};

alert(object.someMethod.displayName); // "undefined"

object.someMethod("123");
alert(object.someMethod.displayName); // "someMethod (123)"
```

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

Обычно оно используется консолью и профилировщиком, как обёртка над `func.name` для отображения имени функции.

Введя следующий пример в консоль, вы должны увидеть что-то вроде "`function Моя функция()`":

```js
var a = function () {};
a.displayName = "Моя функция";

a;
```

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

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

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

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


Function.prototype.call() - JavaScript

Function.prototype.call()
=========================

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

Метод **`call()`** вызывает функцию с указанным значением `this` и индивидуально предоставленными аргументами.

**Примечание:** хотя синтаксис этой функции практически полностью идентичен функции `apply()`, фундаментальное различие между ними заключается в том, что функция `call()` принимает **список аргументов**, в то время, как функция `apply()` **- одиночный массив аргументов**.

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

fun.call(thisArg[, arg1[, arg2[, ...]]])
```

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

`thisArg`

Значение `this`, предоставляемое для вызова функции *`fun`*. Обратите внимание, что `this` может не быть реальным значением, видимым этим методом: если метод является функцией в нестрогом режиме (en-US), значения `null` и `undefined` будут заменены глобальным объектом, а примитивные значения будут упакованы в объекты.

`arg1, arg2, ...`

Аргументы для объекта.

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

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

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

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

Вы можете использовать метод `call` для объединения в цепочку конструкторов объекта, как в Java. В следующем примере для объекта продукта `Product` объявлен конструктор с двумя параметрами, названием `name` и ценой `price`. Продукт инициализирует свойства `name` и `price`, а специализированные функции определяют ещё категорию `category`.

```js
function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError(
      "Нельзя создать продукт " + this.name + " с отрицательной ценой",
    );
  }
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = "еда";
}

Food.prototype = Object.create(Product.prototype);

function Toy(name, price) {
  Product.call(this, name, price);
  this.category = "игрушка";
}

Toy.prototype = Object.create(Product.prototype);

var cheese = new Food("фета", 5);
var fun = new Toy("робот", 40);
```

### Пример: использование `call` для вызова анонимной функции

В этом чисто искусственном примере, мы создаём анонимную функцию и используем `call` для вызова её на каждом элементе массива. Главная задача анонимной функции здесь — добавить функцию печати в каждый объект, способную напечатать правильный индекс объекта в массиве. Передача объекта в качестве значения `this` не является острой необходимостью, но мы делаем это в целях объяснения.

```js
var animals = [
  { species: "Лев", name: "Король" },
  { species: "Кит", name: "Фэйл" },
];

for (var i = 0; i < animals.length; i++) {
  (function (i) {
    this.print = function () {
      console.log("#" + i + " " + this.species + ": " + this.name);
    };
    this.print();
  }).call(animals[i], i);
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function.prototype.call |

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

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

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

* `Function.prototype.bind()`
* `Function.prototype.apply()`


Function.name - JavaScript

Function.name
=============

Read-only свойство **`name`** глобального объекта `Function` и его экземпляров содержит название функции созданное во время определения функции или присваивания ссылки на функцию переменной, свойству, аргументу и т. п. Для анонимных функций это свойство может иметь значение `"anonymous"` или пустую строку `""`.

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

Интерактивные примеры размещены в GitHub репозитории. Если вы хотите добавить свои примеры, то клонируйте https://github.com/mdn/interactive-examples и пришлите пул реквест.

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

**Примечание:** Заметьте, что в нестандартном, pre-ES2015 релизе `configurable` свойство было `false`

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

### Имя объявленной функции

Свойство `name` возвращает имя функции, либо пустую строку для анонимных функций:

```js
function doSomething() {}

alert(doSomething.name); // выведет "doSomething"
```

### Имя функции-конструктора

Функции, созданные синтаксисом `new Function(...)` или просто `Function(...)` создают `Function` и имеют name "anonymous":

```js
new Function().name; // "anonymous"
```

### Предполагаемые имена функций

Переменные и методы могут предположить название анонимной функции из её синтаксической позиции (new in ECMAScript 2015).

```js
var f = function () {};
var object = {
  someMethod: function () {},
};

console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"
```

Вы можете определить функцию с именем в function expression:

```js
var object = {
  someMethod: function object\_someMethod() {},
};
console.log(object.someMethod.name); // выведет "object\_someMethod"

try {
  object_someMethod;
} catch (e) {
  console.log(e);
}
// ReferenceError: object\_someMethod is not defined
```

Вы не можете изменить имя функции, это свойство только для чтения:

```js
var object = {
  // анонимная функция
  someMethod: function () {},
};

object.someMethod.name = "otherMethod";
alert(object.someMethod.name); //someMethod
```

Для изменения name можно использовать `Object.defineProperty()`.

### Сокращённые имена методов

```js
var o = {
  foo() {},
};
o.foo.name; // "foo";
```

### Имена функций после привязки

`Function.bind()` производит функцию, получающую имя "bound и название самой функции.

```js
function foo() {}
foo.bind({}).name; // "bound foo"
```

### Имена функций для getters и setters

Когда используются `get` и set, "get" и "set" появятся в имени функции.
```

let o = {
  get foo(){},
  set foo(x){}
};

var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo";
```

### Имена функций-классов

Можно использовать `obj.constructor.name` чтобы проверить "class" объекта (читайте предупреждение ниже):
```

function Foo() {}  // ES2015 Syntax: class Foo {}

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs "Foo"
```

**Предупреждение:** Интерпретатор объявит встроенное `Function.name` свойство только если функция не имеет своего собственного свойства *name* (см. 9.2.11 of the ECMAScript2015 Language Specification). Однако, в ES2015 статичные методы перезаписывают OwnProperty конструкторов класса-функции (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).

Таким образом, нельзя получить доступ к `name` любого класса со статичным свойством `name():`

```js
class Foo {
  constructor() {}
  static name() {}
}
```

Со `static name()` методом `Foo.name` больше не содержит название класса, но отсылает к функции `name()`. Приведённое выше определение класса в ES2015 будет вести себя в Chrome и Firefox как в ES5:
```

function Foo() {}
Object.defineProperty(Foo, 'name', { writable: true });
Foo.name = function() {};
```

Пытаясь получить доступ к `fooInstance` с помощью `fooInstance.constructor.name` не даст название класса, но выведет метод `name()`. Пример:
```

let fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs function name()
```

Из ES5 syntax примера также видно, что в Chrome или Firefox статичное определение `Foo.name` становится *записываемым (writable)*. Встроенное определение в отсутствии кастомного статичного метода*доступно только для чтения*:
```

Foo.name = 'Hello';
console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.
```

Следовательно не ожидайте, что `Function.name` свойство будет всегда содержать имя класса.

### Имена функций-символов

Если у `Symbol` объявляется имя, то название метода - это имя квадратных скобках.

```js
let sym1 = Symbol("foo");
let sym2 = Symbol();
let o = {
  [sym1]: function () {},
  [sym2]: function () {},
};

o[sym1].name; // "[foo]"
o[sym2].name; // ""
```

JavaScript минифицированный
---------------------------

**Предупреждение:** Будьте осторожны, используя `Function.name` и изменения source кода с помощью JavaScript compressors (minifiers) или обфускаторов. Эти инструменты часто используются, как встроенные в JavaScript build pipeline, чтобы сократить размер билда перед деплоем в production. Такие трансформации часто изменяют имена функций.

Такой source code:
```

function Foo() {};
let foo = new Foo();

if (foo.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}
```

может быть сжат в:
```

function a() {};
let b = new a();
if (b.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}
```

В несжатой версии код выполняется ожидаемо `"'foo' is an instance of 'Foo'"`. В то время, как в сжатой версии он ведёт себя иначе. Если вы полагаетесь на `Function.name`, как в примере, то убедитесь, что pipeline не меняет код или не ожидайте от функции определённого имени.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-instances-name |

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

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


Конструктор Function() - JavaScript

Конструктор Function()
======================

**Конструктор `Function`** создаёт новый **объект** `Function`. Вызов конструктора напрямую позволяет создавать функции программным путём, однако такой способ представляет угрозу для безопасности, а также несёт разные (хотя не такие значительные) проблемы с производительностью при использовании с `Global_Objects/eval`. Однако в отличие от eval, конструктор `Function` создаёт функции, выполняемые только в глобальной области видимости.

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

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

```js
new Function(arg1, functionBody)
new Function(arg1, arg2, functionBody)
new Function(arg1, ... , argN, functionBody)
```

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

`arg1, arg2, ... argN`

Имена, используемые функцией в качестве имён формальных аргументов. Каждое имя должно быть строкой с правильным JavaScript-значением (либо идентификатором, оставшимся параметром, или деструктурирующим присваиванием, либо списком таких строк, разделённых запятой.

Поскольку параметры разбираются так же, как и объявления функций, допускается использование пробелов и комментариев. Например: `"x", "theValue = 42", "[a, b] /* numbers */"` — или `"x, theValue = 42, [a, b] /* numbers */"`. (`"x, theValue = 42", "[a, b]"` также будет правильным, хотя трудно читаемым).

`functionBody`

Строка, содержащая инструкции JavaScript, составляющие определение функции.

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

Объекты `Function`, созданные конструктором `Function`, разбираются при создании функции. Определение функции при помощи выражения function или инструкции function и вызова её внутри вашего кода более эффективно, поскольку такие функции разбираются вместе с остальным кодом.

Все аргументы, переданные в функцию, трактуются как имена идентификаторов параметров создаваемой функции, и имеют тот же порядок следования, что и при их передаче в конструктор функции. Если опустить аргумент, то значение этого параметра будет `undefined`.

Вызов конструктора `Function` как функции (без использования оператора `new`) имеет тот же самый эффект, что и вызов его как конструктора.

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

### Пример: указание аргументов в конструкторе Function

Следующий код создаёт объект `Function, который принимает два аргумента.

```js
// Пример может быть запущен непосредственно в вашей консоли JavaScript

// Создаём функцию, принимающую два аргумента, и возвращающую их сумму
const adder = new Function("a", "b", "return a + b");

// Вызываем функцию
adder(2, 6);
// 8
```

Аргументы "`a`" и "`b`" являются именами формальных аргументов, которые используются в теле функции, "`return a + b`".

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-constructor |

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

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

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

* Функции и их область видимости
* Инструкция `function`
* Выражение `function`
* Инструкция `function*`
* Выражение `function*`
* `AsyncFunction`
* `GeneratorFunction`


Function.length - JavaScript

Function.length
===============

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

Свойство **`length`** определяет количество аргументов, ожидаемых функцией.

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

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

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

### Свойство данных конструктора `Function`

Конструктор `Function` сам является объектом `Function`. Его свойство данных `length` имеет значение 1. Атрибуты свойства: записываемое: `false`, перечисляемое: `false`, настраиваемое: `true`.

### Свойство объекта прототипа `Function`

Свойство `length` объекта прототипа `Function` имеет значение 0.

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

```js
console.log(Function.length); /\* 1 \*/

console.log(function () {}.length); /\* 0 \*/
console.log(function (a) {}.length); /\* 1 \*/
console.log(function (a, b) {}.length); /\* 2 и так далее \*/
console.log(
  function (...args) {}.length,
); /\* 0, остаточные параметры не считаются \*/
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-instances-length |

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

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

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

* `Function`


Function.caller - JavaScript

Function.caller
===============

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

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

Свойство **`function.caller`** возвращает функцию, которая вызвала указанную функцию.

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

Если функция `f` была вызвана из кода самого верхнего уровня, значение `f.caller` будет равно `null`, в противном случае значение будет равно функции, вызвавшей `f`.

Это свойство пришло на замену удалённого свойства `arguments.caller` объекта `arguments` (en-US).

Специальное свойство `__caller__`, возвращающее объект активации вызывающей функции и, таким образом, позволяющее восстанавливать стек вызовов, было удалено по соображениям безопасности.

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

Обратите внимание, что в случае рекурсии, вы не сможете воссоздать стек вызовов, используя это свойство. Пусть у нас есть функции:

```js
function f(n) {
  g(n - 1);
}
function g(n) {
  if (n > 0) {
    f(n);
  } else {
    stop();
  }
}
f(2);
```

В момент вызова функции `stop()`, стек вызовов имеет следующий вид:
```

f(2) -> g(2) -> f(2) -> g(1) -> f(1) -> g(0) -> stop()
```

Следующее условие верно:
```

stop.caller === g && f.caller === g && g.caller === f
```

так что если вы попытаетесь оттрассировать стек в функции `stop()` подобным образом:

```js
var f = stop;
var stack = "Трассировка стека:";
while (f) {
  stack += "\n" + f.name;
  f = f.caller;
}
```

то этот цикл никогда не остановится.

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

### Пример: проверка значения свойства `caller` функции

Следующий код проверяет значение свойства `caller` функции.

```js
function myFunc() {
  if (myFunc.caller == null) {
    return "Эта функция была вызвана из верхнего уровня!";
  } else {
    return "Эта функция была вызвана из " + myFunc.caller;
  }
}
```

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

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

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

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

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

* Ошибка реализации в SpiderMonkey: Firefox bug 65683


Function.prototype.toString() - JavaScript

Function.prototype.toString()
=============================

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

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

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

function.toString(indentation)
```

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

`indentation`
Non-standard

Количество пробелов для отступов в строковом представлении исходного кода. Если параметр меньше или равен `-1`, большинство ненужных пробелов будет удалено.

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

Объект `Function` переопределяет метод `toString`, унаследованный из объекта `Object`; он не наследует метод `Object.prototype.toString`. Для объектов `Function` метод `toString` возвращает строку, представляющую объект в форме объявления функции. То есть, метод `toString` декомпилирует функцию и возвращает строку, включающую ключевое слово `function`, список аргументов, фигурные скобки и исходный код тела функции.

JavaScript вызывает метод `toString` автоматически в случае, когда объект `Function` представляется в качестве текстового значения, то есть, когда функция соединяется со строкой.

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

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

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

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

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

* `Object.prototype.toString()`


Function.prototype.bind() - JavaScript

Function.prototype.bind()
=========================

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

Метод **`bind()`** создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения `this` предоставленное значение. В метод также передаётся набор аргументов, которые будут установлены перед переданными в привязанную функцию аргументами при её вызове.

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

fun.bind(thisArg[, arg1[, arg2[, ...]]])
```

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

`thisArg`

Значение, передаваемое в качестве `this` в целевую функцию при вызове привязанной функции. Значение игнорируется, если привязанная функция конструируется с помощью оператора `new`.

`arg1, arg2, ...`

Аргументы целевой функции, передаваемые перед аргументами привязанной функции при вызове целевой функции.

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

Метод `bind()` создаёт новую "**привязанную функцию**" (**ПФ**). **ПФ** - это "необычный функциональный объект" ( термин из **ECMAScript 6** ), который является обёрткой над исходным функциональным объектом. Вызов **ПФ** приводит к исполнению кода обёрнутой функции.

**ПФ** имеет следующие внутренние ( скрытые ) свойства:

* **[[BoundTargetFunction]]** - оборачиваемый (целевой ) функциональный объект
* **[[BoundThis]]** - значение, которое всегда передаётся в качестве значения **this** при вызове обёрнутой функции.
* **[[BoundArguments]]** - список значений, элементы которого используются в качестве первого аргумента при вызове оборачиваемой функции.
* **[[Call]]** - внутренний метод. Выполняет код (функциональное выражение), связанный с функциональным объектом.

Когда **ПФ** вызывается, исполняется её внутренний метод **[[Call]]** со следующими аргументами **Call(*target*, *boundThis*, *args*).**

* ***target*** - **[[BoundTargetFunction]]**;
* ***boundThis*** - **[[BoundThis]]**;
* ***args*** - **[[BoundArguments]].**

Привязанная функция также может быть сконструирована с помощью оператора `new`: это работает так, как если бы вместо неё конструировалась целевая функция. Предоставляемое значение `this` в этом случае игнорируется, хотя ведущие аргументы всё ещё передаются в эмулируемую функцию.

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

### Пример: создание привязанной функции

Простейшим способом использования `bind()` является создание функции, которая, вне зависимости от способа её вызова, вызывается с определённым значением `this`. Обычным заблуждением для новичков в JavaScript является извлечение метода из объекта с целью его дальнейшего вызова в качестве функции и ожидание того, что он будет использовать оригинальный объект в качестве своего значения `this` (например, такое может случиться при использовании метода как колбэк-функции). Однако, без специальной обработки, оригинальный объект зачастую теряется. Создание привязанной функции из функции, использующей оригинальный объект, изящно решает эту проблему:

```js
this.x = 9;
var module = {
  x: 81,
  getX: function () {
    return this.x;
  },
};

module.getX(); // 81

var getX = module.getX;
getX(); // 9, поскольку в этом случае this ссылается на глобальный объект

// создаём новую функцию с this, привязанным к module
var boundGetX = getX.bind(module);
boundGetX(); // 81
```

### Пример: частичные функции

Следующим простейшим способом использования `bind()` является создание функции с предопределёнными аргументами. Эти аргументы (если они есть) передаются после значения `this` и вставляются перед аргументами, передаваемыми в целевую функцию при вызове привязанной функции.

```js
function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Создаём функцию с предустановленным ведущим аргументом
var leadingThirtysevenList = list.bind(undefined, 37);

var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
```

### Пример: с `setTimeout`

По умолчанию, внутри `window.setTimeout()` (en-US) контекст `this` устанавливается в объект `window` (или `global`). При работе с методами класса, требующими `this` для ссылки на экземпляры класса, вы можете явно привязать `this` к колбэк-функции для сохранения экземпляра.

```js
function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() \* 12) + 1;
}

// Объявляем цветение с задержкой в 1 секунду
LateBloomer.prototype.bloom = function () {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function () {
  console.log("Я прекрасный цветок с " + this.petalCount + " лепестками!");
};
```

### Пример: привязывание функций, используемых в качестве конструкторов

**Предупреждение:** этот раздел демонстрирует возможности JavaScript и документирует некоторые граничные случаи использования метода `bind()`. Показанные ниже методы не являются лучшей практикой и, вероятно, их не следует использовать в рабочем окружении.

Привязанные функции автоматически подходят для использования вместе с оператором `new` для конструирования новых экземпляров, создаваемых целевой функцией. Когда привязанная функция используется для конструирования значения, предоставляемое значение `this` игнорируется. Однако, предоставляемые аргументы всё так же вставляются перед аргументами конструктора:

```js
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return this.x + "," + this.y;
};

var p = new Point(1, 2);
p.toString(); // '1,2'

var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0 /\*x\*/);
// не поддерживается полифилом, приведённым ниже,
// но отлично работает с родным bind:
var YAxisPoint = Point.bind(null, 0 /\*x\*/);

var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'

axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true
```

Обратите внимание, что вам не нужно делать ничего особенного для создания привязанной функции, используемой с оператором `new`. В итоге, для создания явно вызываемой привязанной функции, вам тоже не нужно делать ничего особенного, даже если вам требуется, чтобы привязанная функция вызывалась только с помощью оператора `new`.

```js
// Пример может быть запущен прямо в вашей консоли JavaScript
// ...продолжение примера выше

// Всё ещё можно вызывать как нормальную функцию
// (хотя обычно это не предполагается)
YAxisPoint(13);

emptyObj.x + "," + emptyObj.y;
// > '0,13'
```

Если вы хотите поддерживать использование привязанной функции только с помощью оператора `new`, либо только с помощью прямого вызова, целевая функция должна предусматривать такие ограничения.

### Пример: создание сокращений

Метод `bind()` также полезен в случаях, если вы хотите создать сокращение для функции, требующей определённое значение `this`.

Возьмём, например, метод `Array.prototype.slice`, который вы можете использовать для преобразования массивоподобного объекта в настоящий массив. Вы можете создать подобное сокращение:

```js
var slice = Array.prototype.slice;

// ...

slice.call(arguments);
```

С помощью метода `bind()`, это сокращение может быть упрощено. В следующем куске кода `slice` является функцией, привязанной к функции `call()` объекта `Function.prototype` (en-US), со значением `this`, установленным в функцию `slice()` объекта `Array.prototype`. Это означает, что дополнительный вызов `call()` может быть устранён:

```js
// Тоже самое, что и slice в предыдущем примере
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);

// ...

slice(arguments);
```

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

Функция `bind` является дополнением к стандарту ECMA-262 5-го издания; поэтому она может присутствовать не во всех браузерах. Вы можете частично обойти это ограничение, вставив следующий код в начало ваших скриптов, он позволяет использовать большую часть возможностей `bind()` в реализациях, не имеющих его родной поддержки.

```js
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // ближайший аналог внутренней функции
      // IsCallable в ECMAScript 5
      throw new TypeError(
        "Function.prototype.bind - what is trying to be bound is not callable",
      );
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
      fToBind = this,
      fNOP = function () {},
      fBound = function () {
        return fToBind.apply(
          this instanceof fNOP && oThis ? this : oThis,
          aArgs.concat(Array.prototype.slice.call(arguments)),
        );
      };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
```

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

* Частичная реализация предполагает, что методы `Array.prototype.slice()`, `Array.prototype.concat()`, `Function.prototype.call()` и `Function.prototype.apply()` являются встроенными, имеют своё первоначальное значение.
* Частичная реализация создаёт функции, не имеющие неизменяемых свойств «отравленной пилюли» — `caller` и `arguments` — которые выбрасывают исключение `TypeError` при попытке получить, установить или удалить эти свойства. (Такие свойства могут быть добавлены, если реализация поддерживает `Object.defineProperty`, либо частично реализованы [без поведения исключение-при-попытке-удаления], если реализация поддерживает расширения `Object.prototype.__defineGetter__()` и `Object.prototype.__defineSetter__()`.)
* Частичная реализация создаёт функции, имеющие свойство `prototype`. (Правильная привязанная функция его не имеет.)
* Частичная реализация создаёт привязанные функции, чьё свойство `length` не соответствует с определением в ECMA-262; оно равно 0, в то время, как полная реализация, в зависимости от значения свойства `length` целевой функции и количества предопределённых аргументов, может вернуть значение, отличное от нуля.

Если вы решили использовать частичную реализацию, **не рассчитывайте на корректную работу в тех случаях, когда реализация отклоняется от спецификации ECMA-262 5-го издания!** Однако, в определённых случаях (и, возможно, с дополнительными модификациями для отдельных нужд), применение данной частичной реализации может быть вполне оправданным до тех пор, пока `bind()` не станет широко реализован в соответствии со спецификацией.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-function.prototype.bind |

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

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

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

* `Function.prototype.apply()`
* `Function.prototype.call()`
* Функции и их область видимости (en-US)


Reflect.deleteProperty() - JavaScript

Reflect.deleteProperty()
========================

Статический метод **`Reflect.deleteProperty()`** позволяет удалять свойства из объекта. Реализация данной функции схожа с оператором `delete`.

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

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

Reflect.deleteProperty(target, propertyKey)
```

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

`target`

Целевой объект в котором будет удалено свойство.

`propertyKey`

Имя удаляемого свойства.

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

`Boolean` указывающий, было ли свойство успешно удалено.

### Исключения

Исключение `TypeError`, если `target` не является `Object`.

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

Метод `Reflect.deleteProperty` позволяет вам удалить свойство объекта. Он возвращает `Boolean` указывающий, было ли свойство успешно удалено. Он так же идентичен оператору `delete` без использования строгого режима.

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

### Использования `Reflect.deleteProperty()`

```js
var obj = { x: 1, y: 2 };
Reflect.deleteProperty(obj, "x"); // true
obj; // { y: 2 }

var arr = [1, 2, 3, 4, 5];
Reflect.deleteProperty(arr, "3"); // true
arr; // [1, 2, 3, , 5]

// Возвращает true даже если такого свойства не существует
Reflect.deleteProperty({}, "foo"); // true

// Возвращает false если такое свойство ненастраиваемое
Reflect.deleteProperty(Object.freeze({ foo: 1 }), "foo"); // false
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.deleteproperty |

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

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

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

* `Reflect`
* `delete` operator


Reflect.defineProperty() - JavaScript

Reflect.defineProperty()
========================

Статический метод **`Reflect.defineProperty()`** похож на `Object.defineProperty()`, но возвращает `Boolean`.

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

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

Reflect.defineProperty(target, propertyKey, attributes)
```

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

`target`

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

`propertyKey`

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

`attributes`

Атрибуты для определяемого или изменяемого свойства.

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

Возвращается значение `Boolean`, указывающее было ли свойство успешно определено.

### Исключения

Исключение `TypeError`, если `target` не является `Object`.

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

Метод `Reflect.defineProperty` позволяет точно дополнить или изменить свойство объекта. Для более подробной информации смотрите на аналогичный метод - `Object.defineProperty`. `Object.defineProperty` возвращает объект или выбрасывает исключение `TypeError`, если свойство не было успешно определено. `Reflect.defineProperty`, в любом случае, просто возвращает `Boolean`, указывающее было ли свойство успешно определено.

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

### Использования `Reflect.defineProperty()`

```js
var obj = {};
Reflect.defineProperty(obj, "x", { value: 7 }); // true
obj.x; // 7
```

### Проверка успешно ли было определено свойство

При использовании `Object.defineProperty`, который возвращал объект в случае успеха, либо выбрасывал исключение `TypeError`, вы должны были использовать конструкцию `try...catch` для того, чтобы поймать ошибку, которая случилась при определении свойства. Потому что `Reflect.defineProperty` возвращает `Boolean` в любом случае, вы можете использовать конструкцию `if...else`:

```js
if (Reflect.defineProperty(target, property, attributes)) {
  // успех
} else {
  // неудача
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.defineproperty |

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

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

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

* `Reflect`
* `Object.defineProperty()`


Reflect.construct() - JavaScript

Reflect.construct()
===================

Статический метод **`Reflect.construct()`** работает как `new` operator. Он эквивалентен `new target(...args)`. Это также даёт дополнительную возможность указать другой прототип.

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

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

Reflect.construct(target, argumentsList[, newTarget])
```

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

`target`

Целевая функция для вызова.

`argumentsList`

Массивоподобный объект указывающий аргументы, с которыми `target` должна вызываться.

`newTarget` Необязательный

Конструктор, чей прототип должен быть использован. Смотрите также `new.target` оператор. Если `newTarget` не указан, то используется `target`.

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

Новый экземпляр `target` (или `newTarget`, если указан), инициализируется `target` как конструктор с заданными аргументами.

### Исключения

Исключение `TypeError`, если `target` или `newTarget` не являются конструкторами.

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

`Reflect.construct()` позволяет вам вызывать конструктор с любым числом аргументов (что также возможно с использованием spread syntax вместе с `new` operator).

```js
var obj = new Foo(...args);
var obj = Reflect.construct(Foo, args);
```

### `Reflect.construct()` против `Object.create()`

До появления `Reflect`, объекты могли быть созданы с использованием произвольной комбинации из конструктора и прототипа при помощи `Object.create()`.

```js
function OneClass() {
  this.name = "one";
}

function OtherClass() {
  this.name = "other";
}

// Данный вызов:
var obj1 = Reflect.construct(OneClass, args, OtherClass);

// ...будет аналогичен данному:
var obj2 = Object.create(OtherClass.prototype);
OneClass.apply(obj2, args);

console.log(obj1.name); // 'one'
console.log(obj2.name); // 'one'

console.log(obj1 instanceof OneClass); // false
console.log(obj2 instanceof OneClass); // false

console.log(obj1 instanceof OtherClass); // true
console.log(obj2 instanceof OtherClass); // true
```

В любом случае, пока конечный результат один и тот же, существует одно важное отличие в этом процессе. При использовании `Object.create()` и `Function.prototype.apply()`, оператор `new.target` будет указывать на `undefined` внутри функции используемой в качестве конструктора, пока ключевое слово `new` не будет использовано для создания объекта.

С другой стороны, в случае вызова `Reflect.construct()`, оператор `new.target` будет указывать на параметр `newTarget` если он задан, или `target` в отличном случае.

```js
function OneClass() {
  console.log("OneClass");
  console.log(new.target);
}
function OtherClass() {
  console.log("OtherClass");
  console.log(new.target);
}

var obj1 = Reflect.construct(OneClass, args);
// Вывод:
// OneClass
// function OneClass { ... }

var obj2 = Reflect.construct(OneClass, args, OtherClass);
// Вывод:
// OneClass
// function OtherClass { ... }

var obj3 = Object.create(OtherClass.prototype);
OneClass.apply(obj3, args);
// Вывод:
// OneClass
// undefined
```

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

### Использования `Reflect.construct()`

```js
var d = Reflect.construct(Date, [1776, 6, 4]);
d instanceof Date; // true
d.getFullYear(); // 1776
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.construct |

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

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

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

* `Reflect`
* `new`
* `new.target`


Reflect.ownKeys() - JavaScript

Reflect.ownKeys()
=================

Статический метод **`Reflect.ownKeys()`** возвращает массив имён, а также `Symbols` собственных полей объекта `target` .

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

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

Reflect.ownKeys(target)
```

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

`target`

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

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

Массив `Array` собственных полей объекта `target`.

### Исключения

Выбрасывает исключение `TypeError`, если `target` не является `Object`.

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

Метод `Reflect.ownKeys` возвращает массив собственных ключей объекта `target`. Эквивалентом этого метода является ``Object.getOwnPropertyNames`(target).concat(`Object.getOwnPropertySymbols`(target))`.

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

### Использование `Reflect.ownKeys()`

```js
Reflect.ownKeys({ z: 3, y: 2, x: 1 }); // [ "z", "y", "x" ]
Reflect.ownKeys([]); // ["length"]

var sym = Symbol.for("comet");
var sym2 = Symbol.for("meteor");
var obj = {
  [sym]: 0,
  str: 0,
  773: 0,
  0: 0,
  [sym2]: 0,
  "-1": 0,
  8: 0,
  "second str": 0,
};
Reflect.ownKeys(obj);
// [ "0", "8", "773", "str", "-1", "second str", Symbol(comet), Symbol(meteor) ]
// Индексы в порядке их перечисления,
// Строки в порядке их ввода,
// Symbols в порядке их ввода
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.ownkeys |

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

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

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

* `Reflect`
* `Object.getOwnPropertyNames()`


Reflect.get() - JavaScript

Reflect.get()
=============

Статический метод **`Reflect.get()`** работает также, словно если бы мы получали свойство объекта (`target[propertyKey]`) с помощью функции.

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

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

Reflect.get(target, propertyKey[, receiver])
```

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

`target`

Объект, к свойству которого идёт обращение.

`propertyKey`

Название свойства, значение которого необходимо получить.

receiver Необязательный

Значение, которое получит переменная `this` при вызове геттера.

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

Значение свойства `propertyKey`.

### Исключения

`TypeError`, если `target` не `Object`.

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

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

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

### Использование `Reflect.get()`

```js
// Объект
var obj = { x: 1, y: 2 };
Reflect.get(obj, "x"); // 1

// Массив
Reflect.get(["ноль", "один"], 1); // "один"

// Proxy, перехватывающий get
var x = { p: 1 };
var obj = new Proxy(x, {
  get(t, k, r) {
    return k + "bar";
  },
});
Reflect.get(obj, "foo"); // "foobar"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.get |

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

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

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

* `Reflect`
* Property accessors


Reflect.apply() - JavaScript

Reflect.apply()
===============

Статический метод **`Reflect.apply()`** вызывает переданную ему функцию с указанными аргументами.

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

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

Reflect.apply(target, thisArgument, argumentsList)
```

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

target

Функция, которую необходимо вызвать.

thisArgument

Значение переменной `this` во время вызова функции *`target`*.

argumentsList

Объект, подобный массиву, содержащий аргументы, с которыми должна быть вызвана функция *`target`*.

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

Возвращается значение, которое вернёт функция *`target`* с указанным значением переменной **`this`** и аргументами.

### Исключения

`TypeError`, если функция `target` не может быть вызвана.

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

В ES5, обычно используется метод `Function.prototype.apply()`, чтобы вызвать функцию с указанным значением переменной `this` и `arguments`, переданными как массив (или массивоподобный объект).

```js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
```

С использованием `Reflect.apply` это действие становится более понятным и занимает меньше места в коде.

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

### Использование `Reflect.apply()`

```js
Reflect.apply(Math.floor, undefined, [1.75]);
// 1;

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"

Reflect.apply(RegExp.prototype.exec, /вы/, [
  "превысокомногорассмотрительствующий",
]).index;
// 4

Reflect.apply("".charAt, "пони", [3]);
// "и"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect.apply |

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

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

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

* `Reflect`
* `Function.prototype.apply()`


DataView.prototype.setInt16() - JavaScript

DataView.prototype.setInt16()
=============================

Метод **`setInt16()`** содержит 16-битное целое (short) значение в байте, смещённым по указанному числу от начала `DataView`.Интерактивный пример
--------------------

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

dataview.setInt16(byteOffset, value [, littleEndian])
```

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

byteOffset

Смещение в байтах от старта до этого значения, где будут храниться данные.

value

Устанавливаемое значение.

littleEndian

Необязательный Указывает, сохранять ли 16-bit целое в little- or big-endian (en-US) формате. Если значение false или undefined, записывает значение big-endian.

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

`undefined`.

### Возвращаемые ошибки

`RangeError`

Выдана, если `byteOffset` установлен так, что целое бы хранилось после конца.

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

### Использование метода `setInt16`

```js
var buffer = new ArrayBuffer(8);
var dataview = new DataView(buffer);
dataview.setInt16(1, 3);
dataview.getInt16(1); // 3
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-dataview.prototype.setint16 |

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

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

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

* `DataView`
* `ArrayBuffer`