TypedArray - JavaScript

TypedArray
==========

Объект ***TypedArray*** (типизированный массив) это массивоподобное представление нижележащего буфера с бинарными данными (ArrayBuffer). Нет ни глобального свойства `TypedArray`, ни открытого конструктора *`TypedArray`*. Но существует ряд глобальных элементов, которые являются конструкторами типизированных массивов для конкретно заданных типов данных. Они приведены ниже. Далее вы найдёте общие свойства и функции, которые можно использовать с любыми типизированными массивами.

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

new TypedArray(); // новое в ES2017
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);

где TypedArray() это одно из следующих значений:

Int8Array(), Uint8Array(), Uint8ClampedArray(), Int16Array(), Uint16Array(), Int32Array(), Uint32Array(), Float32Array(), Float64Array()
```

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

length

При вызове в памяти создаётся буфер длины **`length`** *BYTES\_PER\_ELEMENT* байт, содержащий нули

typedArray

Когда вызывается с аргументом **`typedArray`**, который может быть объектом любого из типов типизированных массивов (например, `Int32Array`), тогда переданный массив `typedArray` копируется в новый массив. Каждое значение из `typedArray` конвертируется в соответствующий конструктору тип прямо перед копированием. Длина нового объекта `typedArray` будет такой же как и длина переданного в параметре `typedArray`

object

Новый массив создаётся так, как если бы была вызвана функция `TypedArray.from()`

buffer, byteOffset, length

Когда происходит вызов с параметрами **`buffer`** и опциональными параметрами **`byteOffset`** и **`length`**, то будет создан новый типизированный массив, который будет отражать `buffer` типа `ArrayBuffer`. Параметры `byteOffset` и `length` определяют диапазон (размер) памяти, выводимый данным массивоподобным представлением. Если оба этих параметра (`byteOffset` и `length`) опущены, то будет использован весь буфер `buffer`; если опущен только `length`, то будет выведен весь остаток буфера после смещения начала отсчёта элементов, заданного параметром `byteOffset`.

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

ECMAScript 2015 определяет конструктор объекта *TypedArray,* который является прототипом всех *TypedArray*-конструкторов. Этот конструктор не открыт явным образом: какое-либо глобальное свойство *`%TypedArray%`* или *`TypedArray`* отсутствует. Он доступен только через `Object.getPrototypeOf(...) (`например`, Int8Array.prototype)`. Все `TypedArray`s конструкторы наследуют общие свойства от конструктора `%TypedArray%`. Кроме того, все прототипы типизированных массивов (`TypedArray.prototype`) имеют своим прототипом `%TypedArray%.prototype`.

Сам по себе конструктор `%TypedArray%` не имеет пользы. Его вызов напрямую или через оператор `new` выдаст ошибку `TypeError`, кроме случая, когда он используется во время создания объектов в JS-движке, поддерживающего подклассы. В настоящее время такие движки неизвестны, поэтому `%TypedArray%` используется только для дополнения функциональности (затычка) браузеров в конструкторах *TypedArray*.

Когда создаётся экземпляр *TypedArray* (например, `Int8Array`), то буферный массив создаётся в памяти, в случае если объект `ArrayBuffer` передаётся как аргумент конструктора, то вместо создания буфера используется он. Адрес буфера сохраняется во внутреннем свойстве экземпляра, и все методы из `%TypedArray%.prototype`, например сеттеры и геттеры, оперируют с буфером, по этому адресу.

### Доступ к свойствам

Получить доступ к элементам массива можно используя стандартный синтаксис по индексу (например, `arr[12]`). Однако, получение и установка индексируемых свойств по цепи прототипов не будет происходить даже в случае, когда вы пытаетесь использовать индексы извне массива. Индексируемые свойства обращаются к элементам буфера `ArrayBuffer` и не имеют отношения к объектным свойствам. Также можно использовать именованные свойства как и в обычных объектах.

```js
//Установка и получение используя стандартный синтаксис массивов
var int16 = new Int16Array(2);
int16[0] = 42;
console.log(int16[0]); // 42

//Отсутствует обращение к свойству прототипа (элемент №20 должен бы иметь значение "foo")
Int8Array.prototype[20] = "foo";
new Int8Array(32)[20]; // 0
//Отсутствует даже в случае обращения к индексу извне текущего массива
Int8Array.prototype[20] = "foo";
new Int8Array(8)[20]; // undefined
// также в случае отрицательных индексов
Int8Array.prototype[-1] = "foo";
new Int8Array(8)[-1]; // undefined

// Допустимы именованные свойства
Int8Array.prototype.foo = "bar";
new Int8Array(32).foo; // "bar"
```

Объекты TypedArray
------------------

| Тип | Диапазон значений | Размер (байты) | Описание | Тип Web IDL | Эквивалентный тип языка C |
| --- | --- | --- | --- | --- | --- |
| `Int8Array` | -128 до 127 | 1 | 8-битное целое со знаком с дополнением до двух | `byte` | `int8_t` |
| `Uint8Array` (en-US) | 0 до 255 | 1 | 8-битное беззнаковое целое | `octet` | `uint8_t` |
| `Uint8ClampedArray` | 0 до 255 | 1 | 8-битное беззнаковое целое (фиксированное от 0 до 255) | `octet` | `uint8_t` |
| `Int16Array` (en-US) | -32768 до 32767 | 2 | 16-битное целое со знаком с дополнением до двух | `short` | `int16_t` |
| `Uint16Array` (en-US) | 0 до 65535 | 2 | 16-битное беззнаковое целое | `unsigned short` | `uint16_t` |
| `Int32Array` | -2147483648 до 2147483647 | 4 | 32-битное целое со знаком с дополнением до двух | `long` | `int32_t` |
| `Uint32Array` (en-US) | 0 до 4294967295 | 4 | 32-битное беззнаковое целое | `unsigned long` | `uint32_t` |
| `Float32Array` | 1.2x10-38 to 3.4x1038 | 4 | 32-битное число с плавающей точкой IEEE-стандарта (7 значащих цифр, например 1.123456) | `unrestricted float` | `float` |
| `Float64Array` | 5.0x10-324 to 1.8x10308 | 8 | 64-битное число с плавающей точкой IEEE-стандарта (16 значащих цифр, например, 1.123...15) | `unrestricted double` | `double` |

Свойства
--------

`TypedArray.BYTES_PER_ELEMENT`

Возвращает размер элемента для разных типизированных массивов.

*TypedArray*.length

Свойство "Длина", значение которого 0.

`TypedArray.name` (en-US)

Возвращает строковое имя конструктора. Например, "Int8Array".

`get TypedArray[@@species]`

Конструктор. Используется для создания производных объектов.

`TypedArray.prototype` (en-US)

Прототип для *TypedArray*-объектов.

Методы
------

`TypedArray.from()` (en-US)

Создаёт типизированный массив из массивоподобного или перечислимого объекта. Смотрите `Array.from()`.

`TypedArray.of()` (en-US)

Создаёт новый типизированный массив с переменным числом аргументов, из которых создастся массив. Смотрите `Array.of()`.

Прототип TypedArray
-------------------

Все TypedArrays-массивы наследуют от `TypedArray.prototype` (en-US).

### Полифилы (дополнители) методов

Многие методы, используемые в TypedArray, могут быть подменены, используя методы, присутствующие среди стандартных в прототипе Arrays. Следующий кусок Javascript-кода демонстрирует, как вы можете дополнить недостающие методы Typed Array.

```js
var typedArrayTypes = [
  Int8Array,
  Uint8Array,
  Uint8ClampedArray,
  Int16Array,
  Uint16Array,
  Int32Array,
  Uint32Array,
  Float32Array,
  Float64Array,
];

for (var k in typedArrayTypes)
  for (var v in Array.prototype)
    if (
      Array.prototype.hasOwnProperty(v) &&
      !typedArrayTypes[k].prototype.hasOwnProperty(v)
    )
      typedArrayTypes[k].prototype[v] = Array.prototype[v];
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-typedarray-objects |

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

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

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

* JavaScript typed arrays
* `ArrayBuffer`
* `DataView`


AsyncFunction - JavaScript

AsyncFunction
=============

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2017.

* Learn more
* See full compatibility
* Report feedback
Объект **`AsyncFunction`** предоставляет методы для асинхронных функций. В JavaScript каждая асинхронная функция фактически является объектом `AsyncFunction`.

Обратите внимание, что `AsyncFunction` *не* является глобальным объектом. Его можно получить с помощью следующего кода:

```js
const AsyncFunction = async function () {}.constructor;
```

`AsyncFunction` является подклассом `Function`.

Конструктор
-----------

`AsyncFunction()` (en-US)

Создаёт новый объект `AsyncFunction`.

Свойства экземпляра
-------------------

*Также наследует свойства своего родителя `Function`*.

Эти свойства определены в `AsyncFunction.prototype` и есть у всех экземпляров `AsyncFunction`.

`AsyncFunction.prototype.constructor`

Функция-конструктор, создающая экземпляр объекта. Для экземпляров `AsyncFunction` начальным значением является конструктор `AsyncFunction` (en-US).

`AsyncFunction.prototype[@@toStringTag]`

Начальным значением свойства `@@toStringTag` является строка `"AsyncFunction"`. Это свойство используется в `Object.prototype.toString()`.

**Примечание:** Экземпляры `AsyncFunction` не имею свойства `prototype` (en-US).

Методы экземпляра
-----------------

*Наследует методы своего родителя `Function`*.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-function-objects |

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

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

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

* `async function`
* Выражение `async function`
* `Function`
* `AsyncGeneratorFunction` (en-US)
* `GeneratorFunction`
* Functions


unescape() - JavaScript

unescape()
==========

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

Устаревший метод **`unescape(str)`** создаёт новую строку в которой шестнадцатеричная последовательность символов вида %xx заменяется эквивалентами из кодировки ASCII. Знаки, закодированные в формате %uxxxx (знаки Юникода), заменяются знаками Юникода в шестнадцатеричной кодировке xxxx.

Последовательность может быть результатом работы функции вроде `escape`. Т.к. `unescape` является устаревшей, используйте `decodeURI` или `decodeURIComponent` вместо неё.

**Примечание:** Не рекомендуется использовать `unescape` чтобы декодировать URI, используйте `decodeURI` вместо него.

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

unescape(str)
```

### Parameters

`str`

Строка которую необходимо преобразовать

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

`Функция unescape` это свойство *глобального объекта*.

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

```js
unescape("abc123"); // "abc123"
unescape("%E4%F6%FC"); // "äöü"
unescape("%u0107"); // "ć"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-unescape-string |

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

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

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

* `decodeURI`
* `decodeURIComponent`


Uint8ClampedArray - JavaScript

Uint8ClampedArray
=================

Типизированный массив **`Uint8ClampedArray`** — это массив, служащий для хранения 8-битных беззнаковых чисел, обрезаемых до диапазона от 0 до 255. Если значение меньше 0, то оно будет приведено к 0 , и к 255, если оно больше 255. Числа с плавающей точкой округляются с помощью математического округления. Массив инициализируется нулями. После того как значение установлено, вы можете ссылаться на него с помощью методов объекта или через стандартный синтаксис массивов (то есть, брать значения с помощью квадратных скобок).

Syntax
------
```

new Uint8ClampedArray(length);
new Uint8ClampedArray(typedArray);
new Uint8ClampedArray(object);
new Uint8ClampedArray(buffer [, byteOffset [, length]]);
```

Для более подробной информации, смотрите *TypedArray*.

Properties
----------

`Uint8ClampedArray.BYTES_PER_ELEMENT`

Возвращает размер элемента в байтах. Для Uint8ClampedArray оно равно 1.

Uint8ClampedArray.length

Static length property whose value is 3. For the actual length (number of elements), see `Uint8ClampedArray.prototype.length` (en-US).

`Uint8ClampedArray.name` (en-US)

Returns the string value of the constructor name. In the case of the `Uint8ClampedArray` type: "Uint8ClampedArray".

`Uint8ClampedArray.prototype` (en-US)

Prototype for the *TypedArray* objects.

Methods
-------

`Uint8ClampedArray.from()` (en-US)

Creates a new `Uint8ClampedArray` from an array-like or iterable object. See also `Array.from()`.

`Uint8ClampedArray.of()` (en-US)

Creates a new `Uint8ClampedArray` with a variable number of arguments. See also `Array.of()`.

`Uint8ClampedArray` prototype
-----------------------------

All `Uint8ClampedArray` objects inherit from `%TypedArray%.prototype` (en-US).

### Properties

`Uint8ClampedArray.prototype.constructor`

Returns the function that created an instance's prototype. This is the `Uint8ClampedArray` constructor by default.

`Uint8ClampedArray.prototype.buffer` (en-US) Только для чтения

Returns the `ArrayBuffer` referenced by the `Uint8ClampedArray` Fixed at construction time and thus **read only**.

`Uint8ClampedArray.prototype.byteLength` (en-US) Только для чтения

Returns the length (in bytes) of the `Uint8ClampedArray` from the start of its `ArrayBuffer`. Fixed at construction time and thus **read only.**

`Uint8ClampedArray.prototype.byteOffset` (en-US) Только для чтения

Returns the offset (in bytes) of the `Uint8ClampedArray` from the start of its `ArrayBuffer`. Fixed at construction time and thus **read only.**

`Uint8ClampedArray.prototype.length` (en-US) Только для чтения

Returns the number of elements hold in the `UintClamped8Array`. Fixed at construction time and thus **read only.**

### Methods

`Uint8ClampedArray.prototype.copyWithin()` (en-US)

Copies a sequence of array elements within the array. See also `Array.prototype.copyWithin()`.

`Uint8ClampedArray.prototype.entries()` (en-US)

Returns a new `Array Iterator` object that contains the key/value pairs for each index in the array. See also `Array.prototype.entries()`.

`Uint8ClampedArray.prototype.every()` (en-US)

Tests whether all elements in the array pass the test provided by a function. See also `Array.prototype.every()`.

`Uint8ClampedArray.prototype.fill()` (en-US)

Fills all the elements of an array from a start index to an end index with a static value. See also `Array.prototype.fill()`.

`Uint8ClampedArray.prototype.filter()` (en-US)

Creates a new array with all of the elements of this array for which the provided filtering function returns true. See also `Array.prototype.filter()`.

`Uint8ClampedArray.prototype.find()` (en-US)

Returns the found value in the array, if an element in the array satisfies the provided testing function or `undefined` if not found. See also `Array.prototype.find()`.

`Uint8ClampedArray.prototype.findIndex()` (en-US)

Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. See also `Array.prototype.findIndex()`.

`Uint8ClampedArray.prototype.forEach()` (en-US)

Calls a function for each element in the array. See also `Array.prototype.forEach()`.

`Uint8ClampedArray.prototype.includes()` (en-US)
Экспериментальная возможность

Determines whether a typed array includes a certain element, returning `true` or `false` as appropriate. See also `Array.prototype.includes()`.

`Uint8ClampedArray.prototype.indexOf()` (en-US)

Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. See also `Array.prototype.indexOf()`.

`Uint8ClampedArray.prototype.join()`

Joins all elements of an array into a string. See also `Array.prototype.join()`.

`Uint8ClampedArray.prototype.keys()` (en-US)

Returns a new `Array Iterator` that contains the keys for each index in the array. See also `Array.prototype.keys()`.

`Uint8ClampedArray.prototype.lastIndexOf()` (en-US)

Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. See also `Array.prototype.lastIndexOf()`.

`Uint8ClampedArray.prototype.map()` (en-US)

Creates a new array with the results of calling a provided function on every element in this array. See also `Array.prototype.map()`.

`Uint8ClampedArray.prototype.move()`
Non-standard
 Не реализовано

Former non-standard version of `Uint8ClampedArray.prototype.copyWithin()` (en-US).

`Uint8ClampedArray.prototype.reduce()` (en-US)

Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. See also `Array.prototype.reduce()`.

`Uint8ClampedArray.prototype.reduceRight()` (en-US)

Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. See also `Array.prototype.reduceRight()`.

`Uint8ClampedArray.prototype.reverse()` (en-US)

Reverses the order of the elements of an array — the first becomes the last, and the last becomes the first. See also `Array.prototype.reverse()`.

`Uint8ClampedArray.prototype.set()`

Stores multiple values in the typed array, reading input values from a specified array.

`Uint8ClampedArray.prototype.slice()` (en-US)

Extracts a section of an array and returns a new array. See also `Array.prototype.slice()`.

`Uint8ClampedArray.prototype.some()` (en-US)

Returns true if at least one element in this array satisfies the provided testing function. See also `Array.prototype.some()`.

`Uint8ClampedArray.prototype.sort()` (en-US)

Sorts the elements of an array in place and returns the array. See also `Array.prototype.sort()`.

`Uint8ClampedArray.prototype.subarray()` (en-US)

Returns a new `Uint8ClampedArray` from the given start and end element index.

`Uint8ClampedArray.prototype.values()` (en-US)

Returns a new `Array Iterator` object that contains the values for each index in the array. See also `Array.prototype.values()`.

`Uint8ClampedArray.prototype.toLocaleString()` (en-US)

Returns a localized string representing the array and its elements. See also `Array.prototype.toLocaleString()`.

`Uint8ClampedArray.prototype.toString()` (en-US)

Returns a string representing the array and its elements. See also `Array.prototype.toString()`.

`Uint8ClampedArray.prototype[@@iterator]()` (en-US)

Returns a new `Array Iterator` object that contains the values for each index in the array.

Examples
--------

```js
// From a length
var uintc8 = new Uint8ClampedArray(2);
uintc8[0] = 42;
uintc8[1] = 1337;
console.log(uintc8[0]); // 42
console.log(uintc8[1]); // 255 (clamped)
console.log(uintc8.length); // 2
console.log(uintc8.BYTES\_PER\_ELEMENT); // 1

// From an array
var arr = new Uint8ClampedArray([21, 31]);
console.log(arr[1]); // 31

// From another TypedArray
var x = new Uint8ClampedArray([21, 31]);
var y = new Uint8ClampedArray(x);
console.log(y[0]); // 21

// From an ArrayBuffer
var buffer = new ArrayBuffer(8);
var z = new Uint8ClampedArray(buffer, 1, 4);
```

Specifications
--------------

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

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

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

Compatibility notes
-------------------

Starting with ECMAScript 2015 (ES6), `Uint8ClampedArray` constructors require to be constructed with a `new` operator. Calling a `Uint8ClampedArray` constructor as a function without `new`, will throw a `TypeError` from now on.

```js
var dv = Uint8ClampedArray([1, 2, 3]);
// TypeError: calling a builtin Uint8ClampedArray constructor
// without new is forbidden
```

```js
var dv = new Uint8ClampedArray([1, 2, 3]);
```

See also
--------

* JavaScript typed arrays
* `ArrayBuffer`
* `DataView`


eval() - JavaScript

eval()
======

**Предупреждение:** Выполнение кода JavaScript с текстовой строки - это невероятный риск для безопасности. Злоумышленнику слишком легко запустить какой угодно код, когда вы используете `eval()`. Смотрите Никогда не используйте eval()!, ниже.

Метод **`eval()`** выполняет JavaScript-код, представленный строкой.

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

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

eval(string)
```

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

`string`

Строка, представленная JavaScript выражением, оператором или последовательностью операторов. Выражение может содержать переменные и свойства существующих объектов.

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

Возвращает значение выполнения кода, переданного в функцию в виде строки. Если код не возвращает ничего - будет возвращено значение `undefined`.

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

`eval()` - функция глобального объекта.

Аргумент функции `eval()` - строка. `eval()` исполняет содержащееся в строке выражение, один или несколько операторов JavaScript. Не стоит вызывать `eval()` для определения значения арифметического выражения; JavaScript вычисляет их автоматически.

`eval()` можно использовать для вычисления значения арифметического выражения, записанного в строковом виде, на более поздней стадии исполнения. Предположим, существует переменная `x`. Можно отложить вычисление выражения, в котором содержится `х`, если присвоить переменной это выражение в виде строки (допустим, "`3 * x + 2`"), а затем вызвать `eval()` в более поздней точке кода.

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

```js
eval(new String("2 + 2")); // возвращает объект типа String, содержащий "2 + 2"
eval("2 + 2"); // возвращает 4
```

Это ограничение легко обойти при помощи `toString()`.

```js
var expression = new String("2 + 2");
eval(expression.toString());
```

Если вы используете `eval` косвенно, вызовом его через ссылку, а не просто `eval`, в ECMAScript 5 это работает в глобальной области видимости, а не в локальной; это значит, что `eval` будет вызван в глобальной области видимости, а код будет выполнен с отсутствием доступа к локальным переменным в пределах области видимости, где он был вызван.

```js
function test() {
  var x = 2,
    y = 4;
  console.log(eval("x + y")); // Прямой вызов, использует локальную области видимости, результат - 6
  var geval = eval;
  console.log(geval("x + y")); // Непрямой вызов, использует глобальную область видимости, бросит ReferenceError, т.к. `x` - не определён
}
```

`Не используйте eval без необходимости!`
----------------------------------------

`eval()` - опасная функция, которая выполняет код, проходящий со всеми привилегиями вызывателя. Если вы запускаете `eval()` со строкой, на которую могут влиять злоумышленники, то вы можете запустить вредоносный код на устройство пользователя с правами вашей веб-страницы/расширения. Наиболее важно, код третьей стороны может видеть область видимости, в которой был вызван `eval()`, что может может привести к атакам, похожим на `Function`.

`Также eval()`, как правило, медленнее альтернатив, так как вызывает интерпретатор JS, тогда как многие другие конструкции оптимизированы современными JS движками.

Есть безопасные (и быстрые!) альтернативы `eval()` для общих случаев использования.

### Доступ к свойствам

Вам не следует использовать `eval()`, чтобы конвертировать имена свойств в свойства. Рассматривая следующий пример, где свойство объекта используемое для доступа неизвестно до выполнения кода. Это можно сделать с eval:

```js
var obj = { a: 20, b: 30 };
var propname = getPropName(); // возвращает "a" или "b"

eval("var result = obj." + propname);
```

Однако, `eval()` здесь не нужен. По факту, использование здесь его удивляет. Вместо него используйте доступ к свойствам, который быстрее и безопаснее:

```js
var obj = { a: 20, b: 30 };
var propname = getPropName(); // возвращает "a" или "b"
var result = obj[propname]; // obj[ "a" ] то же, что и obj.a
```

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

У JavaScript функции первого класса, что значит, что вы можете передавать функции как аргументы, хранить их в переменных или свойствах объектов и так далее. Многие DOM API созданы с учётом этого, так что вы можете (и вам следует) писать:

```js
// вместо setTimeout(" ... ", 1000) :
setTimeout(function() { ... }, 1000);

// вместо elt.setAttribute("onclick", "...") использовать:
elt.addEventListener("click", function() { ... } , false);
```

Замыкания также полезны как способ создания функций с параметрами без конкатенации строк.

### Разбор JSON (конвертирование строк в JavaScript объекты)

Если строка, переданная в `eval()`, содержит данные (к примеру, массив: `"[1, 2, 3]"`), а не код, вам следует рассмотреть JSON, позволяющий строке использовать подмножество JavaScript синтаксиса для представления данных. Смотрите также: Загрузка JSON и JavaScript в расширениях.

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

### Передавайте данные вместо кода

К примеру, расширение, созданное изменять содержимое веб-страниц, должно иметь правила, определённые в XPath (en-US), а не JS коде.

### Выполняйте код с ограниченными правами

Если выполнять код всё-таки необходимо, желательно это делать с уменьшенными привелегиями. Этот совет подходит, главным образом, к расширениям и XUL приложениям, которые могут использовать Components.utils.evalInSandbox.

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

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

В следующем коде оба выражения содержат `eval()`, возвращающий 42. Первое определяется строкой "`x + y + 1`"; второе - строкой "`42`".

```js
var x = 2;
var y = 39;
var z = "42";
eval("x + y + 1"); // возвращает 42
eval(z); // вернёт 42
```

### Использование `eval` для исполнения строки, содержащей операторы JavaScript

Следующий пример использует `eval()` для получения значения выражения `str`. Эта строка состоит из JavaScript выражений, печатающих в консоль, и, если x равен пяти, призывающих z значение 42, или 0 в противном случае. Когда второе выражение будет исполнено, `eval()` будет считать выражения выполненными, а также это установит значение выражению переменной z и вернёт его.

```js
var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0; ";

console.log("z is ", eval(str));
```

### Последнее выражение выполняется

`eval()` вернёт значение последнего выполняемого выражения

```js
var str = "if ( a ) { 1+1; } else { 1+2; }";
var a = true;
var b = eval(str); // вернёт 2

console.log("b is : " + b);

a = false;
b = eval(str); // вернёт 3

console.log("b is : " + b);
```

### `eval` как строковое определение функции, включающее "(" и ")" как префикс и суффикс

```js
var fctStr1 = "function a() {}";
var fctStr2 = "(function a() {})";
var fct1 = eval(fctStr1); // вернёт undefined
var fct2 = eval(fctStr2); // вернёт функцию
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-eval-x |

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

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

### Gecko-специфичные замечания

* Исторически `eval()` имел второй необязательный аргумент, указывающий на то, в контексте какого объекта будет выполняться выражение. Этот аргумент не был стандартизован и был удалён из SpiderMonkey в Gecko 1.9.1 (Firefox 3.5). См. Firefox bug 442333.
Смотрите также
--------------

* `uneval()` (en-US)
* Доступ к свойствам


NaN - JavaScript

NaN
===

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

Глобальное свойство **`NaN`** является значением, представляющим не-число (Not-A-Number).

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

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

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

`NaN` является свойством *глобального объекта*.

Начальным значением `NaN` является Not-A-Number (не-число) — то же самое значение, что и у `Number.NaN`. В современных браузерах `NaN` является ненастраиваемым и незаписываемым свойством. Даже когда это не так, избегайте его переопределения.

В программах `NaN` используется довольно редко. Это возвращаемое значение в ситуациях, когда математические (`Math`) функции не срабатывают должным образом (например, при вызове `Math.sqrt(-1)`) или когда функция, пытающаяся считать число из строки, терпит неудачу по причине того, что в строке не число (`parseInt('blabla')`).

### Проверка на равенство `NaN`

`NaN` является неравным (посредством сравнения через `==`, `!=`, `===`, and `!==`) любому другому значению, включая другое значение NaN. Используйте `Number.isNaN()` или `isNaN()`, чтобы наиболее понятным образом определить является ли значение значением NaN. Или выполните само-сравнение: NaN, и только NaN, в результате такого сравнения будет неравным самому себе.

```js
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true

function valueIsNaN(v) {
  return v !== v;
}
valueIsNaN(1); // false
valueIsNaN(NaN); // true
valueIsNaN(Number.NaN); // true
```

Тем не менее, обратите внимание на разницу между функцией `isNaN()` и методом `Number.isNaN()`: первая вернёт `true`, если значение в настоящий момент является `NaN`, или если оно станет `NaN` после того, как преобразуется в число, в то время как последний вернёт `true`, только если текущим значением является `NaN`:

```js
isNaN("hello world"); // true
Number.isNaN("hello world"); // false
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-value-properties-of-the-global-object-nan |

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

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

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

* `Number.NaN`
* `Number.isNaN()`
* `isNaN()`


WeakMap - JavaScript

WeakMap
=======

**`WeakMap`** — это коллекция пар ключ-значение. В качестве ключей могут быть использованы только объекты и незарегистрированные символы, а значения могут быть произвольных типов.

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

Ключи в WeakMap должны поддерживать сборку мусора. Большинство примитивных типов данных могут не иметь времени жизни, поэтому они не могут быть использованы в качестве ключей. Объекты и незарегистрированные символы могут быть ключами потому что они поддерживают сборку мусора.

### Почему WeakMap?

Опытный JavaScript разработчик заметит, что map API можно реализовать на JavaScript c помощью двух массивов (один для ключей, второй для значений) и четырёх общих API методов. Установка элементов в этот map должна будет одновременно запушить ключи и значения. В результате индексы ключа и значения будут корректными. Получение значений с map потребует итерирование ключей, чтобы найти совпадение, а затем использование индекса этого соответствия для извлечения соответствующего значения из массива значений.

У такой реализации было бы два главных неудобства. Первым является O(n) поиск (где n — количество ключей в map), так как обе операции требуют итерирование списка ключей для нахождения совпадения. Вторым — проблема утечки памяти. В словарях, написанных вручную, массив с ключами будет хранить ссылки на объекты-ключи, не давая им быть помеченными сборщиком мусора. В нативных `WeakMap`, ссылки на объекты-ключи хранятся «слабо», что означает то, что они не предотвратят сборку мусора в том случае, если других ссылок на объект не будет.

WeakMaps имеют "weak" («слабые») обращения к ключам объекта, а следовательно непрепятствие сборщику мусора, когда мы больше не имеем объекта-ключа. WeakMaps могут быть особенно полезными конструкциями при сопоставлении ключей с информацией о ключе, который ценен, только если ключ не был собран сборщиком мусора (Garbage collector).

Из-за того, что ссылки являются слабыми, ключи `WeakMap` не перечисляемы (то есть нет метода, который возвращает список ключей). Иначе список бы зависел от состояния сбора мусора, представляя индетерминизм. Если вы хотите иметь список ключей, вам следует поддерживать его самостоятельно.

Конструктор
-----------

`WeakMap()` (en-US)

Создаёт новый объект `WeakMap`.

Свойства экземпляра
-------------------

Эти свойства определены в `WeakMap.prototype` и есть у всех экземпляров `WeakMap`.

`WeakMap.prototype.constructor`

Функция-конструктор, создающая экземпляр объекта. Для экземпляров `WeakMap` начальным значением является конструктор `WeakMap` (en-US).

`WeakMap.prototype[@@toStringTag]`

Начальным значением свойства `@@toStringTag` является строка `"WeakMap"`. Это свойство используется в `Object.prototype.toString()`.

Методы экземпляра
-----------------

`WeakMap.prototype.delete()`

Удаляет значение, связанное с ключом `key`. После этого `WeakMap.prototype.has(key)` будет возвращать `false`.

`WeakMap.prototype.get()`

Возвращает значение, связанное с ключом `key` или `undefined` если его нет.

`WeakMap.prototype.has()`

Возвращает булево значение, показывающее связано ли значение с ключом `key` в объекте `WeakMap` или нет.

`WeakMap.prototype.set()`

Устанавливает значение `value` для ключа `key` в объекте `WeakMap`. Возвращает объект `WeakMap`.

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

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

```js
const wm1 = new WeakMap();
const wm2 = new WeakMap();
const wm3 = new WeakMap();
const o1 = {};
const o2 = function () {};
const o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "Привет");
wm2.set(o1, o2); // значением может быть что угодно, включая объект или функцию
wm2.set(o2, undefined);
wm2.set(wm1, wm2); // ключами и значениями могут быть объекты и даже WeakMap (!)

wm1.get(o2); // "Привет"
wm2.get(o2); // undefined, потому что такое значение было установлено
wm2.get(o3); // undefined, потому что в wm2 нет ключа o3

wm1.has(o2); // true
wm2.has(o2); // true (даже если само значение равно 'undefined')
wm2.has(o3); // false

wm3.set(o1, 37);
wm3.get(o1); // 37

wm1.has(o1); // true
wm1.delete(o1);
wm1.has(o1); // false
```

### Пример: Реализация класса WeakMap-подобных классов с методом .clear()

```js
class ClearableWeakMap {
  #wm;
  constructor(init) {
    this.#wm = new WeakMap(init);
  }
  clear() {
    this.#wm = new WeakMap();
  }
  delete(k) {
    return this.#wm.delete(k);
  }
  get(k) {
    return this.#wm.get(k);
  }
  has(k) {
    return this.#wm.has(k);
  }
  set(k, v) {
    this.#wm.set(k, v);
    return this;
  }
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-weakmap-objects |

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

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

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

* Полифил `WeakMap` в `core-js`
* Коллекции
* Hiding Implementation Details with ECMAScript 6 WeakMaps
* `Map` (en-US)
* `Set`
* `WeakSet`


Set - JavaScript

Set
===

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

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

Объекты "Set" - это коллекция значений. Значение в `Set` **может встречаться только один раз**; оно уникально в коллекции. Вы можете перебирать элементы набора в порядке вставки. Порядок *вставки* соответствует порядку, в котором каждый элемент был успешно вставлен в коллекцию методом `add()` (то есть, когда был вызван `add()`, в наборе ещё не было такого элемента).

Спецификация требует реализации наборов, "которые в среднем обеспечивают время доступа, сублинейное количеству элементов в коллекции". Следовательно, он может быть представлен внутренне в виде хэш-таблицы (с поиском O(1)), дерева поиска (с поиском O(log(N))) или любой другой структуры данных, при условии, что сложность выше, чем O(N).

### Сравнение значений

При добавлении нового элемента в Set происходит проверка, добавлялся ли такой элемент ранее. Эта проверка использует специальный алгоритм сравнения значений SameValueZero. (Раньше использовался алгоритм SameValue, в котором значения `0` и `-0` считаются разными. Смотрите браузерную поддержку ниже). Это означает, что `NaN` считается равным `NaN` (не смотря на то что `NaN !== NaN`), а все другие значения считаются равными в соответствии с семантикой оператора `===`.

### Производительность

Метод `has` проверяет наличие значения в `Set` используя алгоритм, который в среднем работает быстрее поэлементного перебора добавленных ранее элементов. В частности этот алгоритм работает быстрее чем метод [`Array.prototype.includes`](/ru/docs/Web/JavaScript/Reference/Global\_Objects/Array/includes на массиве, который хранит столько же элементов сколько сравниваемый объект `Set`.

Конструктор
-----------

`Set()`

Создаёт новый объект `Set`.

Статические свойства
--------------------

`get Set[@@species]` (en-US)

Функция-конструктор, которая используется для создания производных объектов.

Свойства экземпляра
-------------------

`Set.prototype[@@toStringTag]`

Начальное значение `@@toStringTag` свойства - строка `"Set"`. Это значение используется в `Object.prototype.toString()`.

`Set.prototype.size`

Возвращает количество значений в объекте `Set`.

Методы экземпляра
-----------------

* `Set.prototype.add()`
    + : Вставляет новый элемент с указанным значением в объект `Set`, если в `Set` ещё нет элемента с таким же значением.
* `Set.prototype.clear()`
    + : Удаляет все значения из объекта `Set`.
* `Set.prototype.delete()`
    + : Удаляет элемент, связанный с переданным значением, и возвращает логическое значение, подтверждающее, был ли элемент успешно удалён или нет. `Set.prototype.has(value)` впоследствии вернет `false`.
* `Set.prototype.has()`
    + : Возвращает логическое значение, утверждающее, присутствует ли элемент с заданным значением в объекте `Set` или нет.
* `Set.prototype[@@iterator]()` (en-US)
    + : Возвращает новый объект итератора, который выдает **значения** для каждого элемента в объекте `Set` в порядке вставки.
* `Set.prototype.values()`
    + : Возвращает новый объект итератора, который выдает **значения** для каждого элемента в объекте `Set` в порядке вставки.
* `Set.prototype.keys()` (en-US)
    + : Аналог `Set.prototype.values()`.
* `Set.prototype.entries()`
    + : Возвращает новый объект итератора, который содержит **массив `[value, value]`** для каждого элемента в объекте `Set` в порядке вставки.Этот метод похож на соответствующий метод объекта `Map` (en-US), но в случае `Set` ключ (*key*) каждой записи совпадает с её значением (*value*).
* `Set.prototype.forEach()`
    + : Вызывает `callbackFn` один раз для каждого значения, присутствующего в объекте `Set` в порядке вставки. Если указан параметр `thisArg`, он будет использоваться в качестве значения `this` для каждого вызова `callbackFn`.
Примеры
-------

### Использование объекта Set

```js
const mySet1 = new Set();

mySet1.add(1); // Set(1) { 1 }
mySet1.add(5); // Set(2) { 1, 5 }
mySet1.add(5); // Set(2) { 1, 5 }
mySet1.add("текст"); // Set(3) { 1, 5, 'текст' }
const o = { a: 1, b: 2 };
mySet1.add(o);

mySet1.add({ a: 1, b: 2 }); // o ссылается на другой объект, так что это нормально

mySet1.has(1); // true
mySet1.has(3); // false, поскольку 3 не был добавлен в набор
mySet1.has(5); // true
mySet1.has(Math.sqrt(25)); // true
mySet1.has("Текст".toLowerCase()); // true
mySet1.has(o); // true

mySet1.size; // 5

mySet1.delete(5); // удаляет элемент 5 из set
mySet1.has(5); // false, 5 был удалён

mySet1.size; // 4, поскольку мы удалили одно значение

mySet1.add(5); // Set(5) { 1, "текст", {...}, {...}, 5 } - ранее удаленный элемент будет добавлен как новый элемент, он не сохранит свое первоначальное положение до удаления

console.log(mySet1); // Set(5) { 1, "текст", {…}, {…}, 5 }
```

### Итерация по объекту Set

Итерация наборов проходит по элементам в порядке вставки.

```js
for (const item of mySet1) {
  console.log(item);
}
// 1, "текст", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5

for (const item of mySet1.keys()) {
  console.log(item);
}
// 1, "текст", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5

for (const item of mySet1.values()) {
  console.log(item);
}
// 1, "текст", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5

// ключ и значение здесь одинаковы
for (const [key, value] of mySet1.entries()) {
  console.log(key);
}
// 1, "текст", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5

// Преобразуем объект Set в объект Array с помощью Array.from
const myArr = Array.from(mySet1); // [1, "текст", {"a": 1, "b": 2}, {"a": 1, "b": 2}, 5]

// следующее также будет работать, если запустить его в HTML-документе
mySet1.add(document.body);
mySet1.has(document.querySelector("body")); // true

// преобразование между Set и Array
const mySet2 = new Set([1, 2, 3, 4]);
console.log(mySet2.size); // 4
console.log([...mySet2]); // [1, 2, 3, 4]

// пересечение можно представить следующим образом
const intersection = new Set([...mySet1].filter((x) => mySet2.has(x)));

// разность можно представить следующим образом
const difference = new Set([...mySet1].filter((x) => !mySet2.has(x)));

// итерироваться можно с помощью forEach()
mySet2.forEach((value) => {
  console.log(value);
});
// 1
// 2
// 3
// 4
```

### Реализация базовых операций Set

```js
function isSuperset(set, subset) {
  for (const elem of subset) {
    if (!set.has(elem)) {
      return false;
    }
  }
  return true;
}

function union(setA, setB) {
  const _union = new Set(setA);
  for (const elem of setB) {
    _union.add(elem);
  }
  return _union;
}

function intersection(setA, setB) {
  const _intersection = new Set();
  for (const elem of setB) {
    if (setA.has(elem)) {
      _intersection.add(elem);
    }
  }
  return _intersection;
}

function symmetricDifference(setA, setB) {
  const _difference = new Set(setA);
  for (const elem of setB) {
    if (_difference.has(elem)) {
      _difference.delete(elem);
    } else {
      _difference.add(elem);
    }
  }
  return _difference;
}

function difference(setA, setB) {
  const _difference = new Set(setA);
  for (const elem of setB) {
    _difference.delete(elem);
  }
  return _difference;
}

// Примеры
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([2, 3]);
const setC = new Set([3, 4, 5, 6]);

isSuperset(setA, setB); // true
union(setA, setC); // Set {1, 2, 3, 4, 5, 6}
intersection(setA, setC); // Set {3, 4}
symmetricDifference(setA, setC); // Set {1, 2, 5, 6}
difference(setA, setC); // Set {1, 2}
```

### Связь с объектами массива

```js
const myArray = ["value1", "value2", "value3"];

// Используйте обычный конструктор Set для преобразования массива в набор
const mySet = new Set(myArray);

mySet.has("value1"); // true

// Используйте синтаксис spread для преобразования набора в массив.
console.log([...mySet]); // Покажет вам точно такой же массив, как и myArray
```

### Удаление повторяющиеся элементов из массива

```js
const numbers = [2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5];

console.log([...new Set(numbers)]); // [2, 3, 4, 5, 6, 7, 32]
```

### Связь со строками

```js
// Чувствительность к регистру (коллекция будет содержать "F" и "f")
new Set("Firefox"); // Set(7) [ "F", "i", "r", "e", "f", "o", "x" ]

// Пропуск дубликатов ("f" встречается два раза в строке, но в коллекции будет только один раз)
new Set("firefox"); // Set(6) [ "f", "i", "r", "e", "o", "x" ]
```

### Используйте Set для обеспечения уникальности списка значений

```js
const array = Array.from(document.querySelectorAll("[id]")).map((e) => e.id);

const set = new Set(array);
console.assert(set.size === array.length);
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-set-objects |

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

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

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

* Полифил `Set` в `core-js`
* map (en-US)
* `WeakMap`
* `WeakSet`


encodeURIComponent() - JavaScript

encodeURIComponent()
====================

**`encodeURIComponent()`** - метод, кодирующий компонент универсального идентификатора ресурса (URI) заменой каждой определённой последовательности символов одной, двумя, тремя или четырьмя последовательностями символов, представленных в кодировке UTF-8 (будет только 4 управляющих последовательности для символов, состоящих из 2 "суррогатных" символов).

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

encodeURIComponent(str);
```

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

`str`

Строка. Компонент URI.

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

`encodeURIComponent` изменяет все символы, за исключением следующих: латинские буквы, десятичные цифры, `- _ . ! ~ * ' ( )`

Замечание: `URIError` будет брошена, если попытаться закодировать суррогат, который не является частью высоко-низкой пары, например:

```js
// низко-высокая пара - нормально
console.log(encodeURIComponent("\uD800\uDFFF"));

// один высокий суррогат бросит "URIError: malformed URI sequence"
console.log(encodeURIComponent("\uD800"));

// один низкий суррогат бросит "URIError: malformed URI sequence"
console.log(encodeURIComponent("\uDFFF"));
```

Чтоб избежать неожиданных запросов к серверу, вам следует вызывать `encodeURIComponent` для любых вводимых пользователем параметров, используемых как часть URI. Например, он мог написать "`Thyme &time=again`" для переменной `comment`. Неиспользование `encodeURIComponent` для неё даст `comment=Thyme%20&time=again`. Заметьте, что амперсанд и знак равно выделяют новую пару ключ-значение. Так что вместо комментария "`Thyme &time=again`", вы получите два POST параметра, один - "`Thyme`", а другой (`time`) равный "`again"`.

`Для application/x-www-form-urlencoded` пробелы должны быть заменены на "+", поэтому вам может понадобиться `encodeURIComponent` с дополнительной заменой "%20" на "+".

Чтобы строго соблюдать RFC 3986 (который резервирует !, ', (, ), и \*), даже не смотря на то, что символы не используют сформированных URI разделителей, можно безопасно использовать следующие:

```js
function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()\*]/g, function (c) {
    return "%" + c.charCodeAt(0).toString(16);
  });
}
```

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

Пример представляет специальное кодирование, требуемое для заголовков сервера в UTF-8: `Content-Disposition` и `Link` (к примеру, имена файлов в UTF-8):

```js
var fileName = "my file(2).txt";
var header =
  "Content-Disposition: attachment; filename\*=UTF-8''" +
  encodeRFC5987ValueChars(fileName);

console.log(header);
// логирует "Content-Disposition: attachment; filename\*=UTF-8''my%20file%282%29.txt"

function encodeRFC5987ValueChars(str) {
  return (
    encodeURIComponent(str)
      // Замечание: хотя RFC3986 резервирует "!", RFC5987 это не делает, так что нам не нужно избегать этого
      .replace(/['()]/g, escape) // i.e., %27 %28 %29
      .replace(/\\*/g, "%2A")
      // Следующее не требуется для кодирования процентов для RFC5987, так что мы можем разрешить немного больше читаемости через провод: |`^
      .replace(/%(?:7C|60|5E)/g, unescape)
  );
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-encodeuricomponent-uricomponent |

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

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

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

* `decodeURI`
* `encodeURI`
* `decodeURIComponent`


Math - JavaScript

Math
====

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

`Math` не работает с числами типа `BigInt`.

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

В отличие от других глобальных объектов, объект `Math` не является конструктором. Все свойства и методы объекта `Math` являются статическими. Вы ссылаетесь на константу π через `Math.PI` и вызываете функцию синуса через `Math.sin(x)`, где `x` является аргументом метода. Константы в JavaScript определены с полной точностью действительных чисел.

Свойства
--------

`Math.E`

Число Эйлера или Непера, основание натуральных логарифмов, приблизительно равное 2,718.

`Math.LN2`

Натуральный логарифм из 2, приблизительно равен 0,693.

`Math.LN10`

Натуральный логарифм из 10, приблизительно равен 2,303.

`Math.LOG2E`

Двоичный логарифм из E, приблизительно равен 1,443.

`Math.LOG10E`

Десятичный логарифм из E, приблизительно равен 0,434.

`Math.PI`

Отношение длины окружности круга к его диаметру, приблизительно равно 3,14159.

`Math.SQRT1_2`

Квадратный корень из 1/2; или, что тоже самое, 1, делённая на квадратный корень из 2, приблизительно равен 0,707.

`Math.SQRT2`

Квадратный корень из 2, приблизительно равен 1,414.

Методы
------

**Примечание:** Обратите внимание, что тригонометрические функции (`sin()`, `cos()`, `tan()`, `asin()`, `acos()`, `atan()` и `atan2()`) принимают в параметрах или возвращают углы в радианах. Для преобразования радианов в градусы, поделите их на величину `(Math.PI / 180)`; для преобразования в обратном направлении, умножьте градусы на эту же величину.

**Примечание:** Обратите внимание, что точность большинства математических функций зависит от реализации. Это означает, что различные браузеры могут дать разные результаты, более того, даже один и тот же движок JavaScript на различных операционных системах или архитектурах может выдать разные результаты.

`Math.abs(x)`

Возвращает абсолютное значение числа.

`Math.acos(x)`

Возвращает арккосинус числа.

`Math.acosh(x)`
Экспериментальная возможность

Возвращает гиперболический арккосинус числа.

`Math.asin(x)`

Возвращает арксинус числа.

`Math.asinh(x)`
Экспериментальная возможность

Возвращает гиперболический арксинус числа.

`Math.atan(x)`

Возвращает арктангенс числа.

`Math.atanh(x)`
Экспериментальная возможность

Возвращает гиперболический арктангенс числа.

`Math.atan2(y, x)`

Возвращает арктангенс от частного своих аргументов.

`Math.cbrt(x)`
Экспериментальная возможность

Возвращает кубический корень числа.

`Math.ceil(x)`

Возвращает значение числа, округлённое к большему целому.

`Math.clz32(x)`
Экспериментальная возможность

Возвращает количество ведущих нулей 32-битного целого числа.

`Math.cos(x)`

Возвращает косинус числа.

`Math.cosh(x)`
Экспериментальная возможность

Возвращает гиперболический косинус числа.

`Math.exp(x)`

Возвращает Ex, где *x* — аргумент, а E — число Эйлера (2,718…), основание натурального логарифма.

`Math.expm1(x)`
Экспериментальная возможность

Возвращает `exp(x)`, из которого вычли единицу.

`Math.floor(x)`

Возвращает значение числа, округлённое к меньшему целому.

`Math.fround(x)`
Экспериментальная возможность

Возвращает ближайшее число с плавающей запятой одинарной точности, представляющие это число.

`Math.hypot([x[, y[, …]]])`
Экспериментальная возможность

Возвращает квадратный корень из суммы квадратов своих аргументов.

`Math.imul(x)`
Экспериментальная возможность

Возвращает результат умножения 32-битных целых чисел.

`Math.log(x)`

Возвращает натуральный логарифм числа (loge, также известен как ln).

`Math.log1p(x)`
Экспериментальная возможность

Возвращает натуральный логарифм числа `1 + x` (loge, также известен как ln).

`Math.log10(x)`
Экспериментальная возможность

Возвращает десятичный логарифм числа.

`Math.log2(x)`
Экспериментальная возможность

Возвращает двоичный логарифм числа.

`Math.max([x[, y[, …]]])`

Возвращает наибольшее число из своих аргументов.

`Math.min([x[, y[, …]]])`

Возвращает наименьшее число из своих аргументов.

`Math.pow(a, n)`

Возвращает `a` в `n`-й степени, то есть *a**n*.

`Math.random()`

Возвращает псевдослучайное число в диапазоне от 0 до 1.

`Math.round(x)`

Возвращает значение числа, округлённое до ближайшего целого.

`Math.sign(x)`
Экспериментальная возможность

Возвращает знак числа, указывающий, является ли число положительным, отрицательным или нулём.

`Math.sin(x)`

Возвращает синус числа.

`Math.sinh(x)`
Экспериментальная возможность

Возвращает гиперболический синус числа.

`Math.sqrt(x)`

Возвращает положительный квадратный корень числа.

`Math.tan(x)`

Возвращает тангенс числа.

`Math.tanh(x)`
Экспериментальная возможность

Возвращает гиперболический тангенс числа.

`Math.toSource()`
Non-standard

Возвращает строку `"Math"`.

`Math.trunc(x)`
Экспериментальная возможность

Возвращает целую часть числа, убирая дробные цифры.

Расширение объекта `Math`
-------------------------

Как и большинство встроенных объектов в Javascript, объект `Math` может быть расширен пользовательскими способами и методами. Чтобы расширить объект `Math`, не используют `prototype`. Вместо этого, расширяют `Math` напрямую:

```js
Math.propName = propValue;
Math.methodName = methodRef;
```

Например, следующий код добавляет метод к объекту Math для вычисления наибольшего общего делителя списка аргументов.

```js
/\* Вариативная функция -- Возвращает наибольший общий делитель списка аргументов \*/
Math.gcd = function () {
  if (arguments.length == 2) {
    if (arguments[1] == 0) return arguments[0];
    else return Math.gcd(arguments[1], arguments[0] % arguments[1]);
  } else if (arguments.length > 2) {
    var result = Math.gcd(arguments[0], arguments[1]);
    for (var i = 2; i < arguments.length; i++)
      result = Math.gcd(result, arguments[i]);
    return result;
  }
};
```

Попробуйте:

```js
console.log(Math.gcd(20, 30, 15, 70, 40)); // `5`
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-math-object |

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

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

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

* `Number`


TypeError - JavaScript

TypeError
=========

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

`TypeError` может возникнуть в следующих случаях:

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

`TypeError` является сериализуемым объектом (en-US), поэтому он может быть клонирован с помощью `structuredClone()` (en-US) или передан между воркерами с использованием `postMessage()`.

`TypeError` является подклассом `Error`.

Конструктор
-----------

`TypeError()` (en-US)

Создаёт новый объект `TypeError`.

Свойства экземпляра
-------------------

*Также наследует свойства своего родителя `Error`*.

Эти свойства определены в `TypeError.prototype` и есть у всех экземпляров `TypeError`.

`TypeError.prototype.constructor`

Функция-конструктор, создающая экземпляр объекта. Для экземпляров `TypeError` начальным значением является конструктор `TypeError` (en-US).

`TypeError.prototype.name`

Представляет название типа ошибки. Начальным значением `TypeError.prototype.name` является `"TypeError"`.

Методы экземпляра
-----------------

*Наследует методы своего родителя `Error`*.

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

### Перехват `TypeError`

```js
try {
  null.f();
} catch (e) {
  console.log(e instanceof TypeError); // true
  console.log(e.message); // "null has no properties"
  console.log(e.name); // "TypeError"
  console.log(e.stack); // Стек ошибок
}
```

### Создание `TypeError`

```js
try {
  throw new TypeError("Привет");
} catch (e) {
  console.log(e instanceof TypeError); // true
  console.log(e.message); // "Привет"
  console.log(e.name); // "TypeError"
  console.log(e.stack); // Стек ошибок
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-native-error-types-used-in-this-standard-typeerror |

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

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

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

* `Error`


Infinity - JavaScript

Infinity
========

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

Глобальное свойство **`Infinity`** является числовым значением, представляющим бесконечность.

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

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

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

`Infinity` является свойством *глобального объекта*, то есть, это переменная в глобальной области видимости.

Начальным значением `Infinity` является `Number.POSITIVE_INFINITY`. Значение `Infinity` (положительная бесконечность) больше любого другого числа, включая саму положительную бесконечность. Это значение ведёт себя как математическая бесконечность; например, любое положительное число, умноженное на `Infinity` даёт `Infinity`, а любое число, делённое на `Infinity` даёт 0.

В спецификации ECMAScript 5 `Infinity` является свойством только для чтения (реализована в JavaScript 1.8.5 / Firefox 4).

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

console.log(Infinity          ); /* Infinity */
console.log(Infinity + 1      ); /* Infinity */
console.log(Math.pow(10, 1000)); /* Infinity */
console.log(Math.log(0)       ); /* -Infinity */
console.log(1 / Infinity      ); /* 0 */
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-value-properties-of-the-global-object-infinity |

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

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

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

* `Number.NEGATIVE_INFINITY`
* `Number.POSITIVE_INFINITY`
* `Number.isFinite`


parseInt() - JavaScript

parseInt()
==========

Функция **`parseInt()`** принимает строку в качестве аргумента и возвращает целое число в соответствии с указанным основанием системы счисления.

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

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

parseInt(string, radix);
```

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

`string`

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

`radix`

Целое число в диапазоне между 2 и 36, представляющее собой основание системы счисления числовой строки `string`, описанной выше. В основном пользователи используют десятичную систему счисления и указывают 10. **Всегда указывайте этот параметр,** чтобы исключить ошибки считывания и гарантировать корректность исполнения и предсказуемость результата. Когда основание системы счисления не указано, разные реализации могут возвращать разные результаты.

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

Целое число, полученное парсингом (разбором и интерпретацией) переданной строки. Если первый символ не получилось сконвертировать в число, то возвращается `NaN`.

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

Функция `parseInt` преобразует первый переданный ей аргумент в строковый тип, интерпретирует его и возвращает целое число или значение `NaN`. Результат (если не `NaN`) является целым числом и представляет собой первый аргумент (`string`), рассматривающийся как число в указанной системе счисления (`radix`). Например, основание 10 указывает на преобразование из десятичного числа, 8 - восьмеричного, 16 - шестнадцатеричного и так далее. Если основание больше `10`, то для обозначения цифр больше `9` используются буквы. Например, для шестнадцатеричных чисел (основание 16) используются буквы от `A` до `F`.

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

Так как некоторые числа включают символ `e` в своём строковом представлении (например, **`6.022e23`**), то использование `parseInt` для усечения числовых значений может дать неожиданные результаты, когда используются очень малые или очень большие величины. `parseInt` не должна использоваться как замена для `Math.floor()`.

Если основание системы счисления имеет значение `undefined` (не определено) или равно 0 (или не указано), то JavaScript по умолчанию предполагает следующее:

* Если значение входного параметра `string` начинается с "`0x`" или "`0X`", *за основание системы счисления принимается 16, и интерпретации подвергается оставшаяся часть строки.*
* Если значение входного параметра `string` начинается с "0", *за основание системы счисления принимается либо 8, либо 10, в зависимости от конкретной реализации.* В спецификации ECMAScript 5 прописано использование 10 (десятичная система), но это поддерживается ещё не всеми браузерами, поэтому необходимо **всегда указывать основание системы счисления при использовании функции** **`parseInt`**.
* Если значение входного параметра `string` начинается с любого другого символа, система счисления считается десятичной (основание 10).

Если первый символ строки не может быть преобразован в число, `parseInt` возвращает значение `NaN`.

С точки зрения математики, значение `NaN` не является числом в какой-либо системе счисления. Чтобы определить, вернёт ли `parseInt` значение `NaN` в качестве результата, можно вызвать функцию `isNaN`. Если `NaN` участвует в арифметических операциях, результатом также будет `NaN`.

Для преобразования числа в строку в указанной системе счисления, используйте `intValue.toString(radix)`.

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

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

Все следующие примеры возвращают **`15`**:

```js
parseInt(" 0xF", 16);
parseInt(" F", 16);
parseInt("17", 8);
parseInt(021, 8);
parseInt("015", 10); //parseInt(015, 10); вернёт 15
parseInt(15.99, 10);
parseInt("FXX123", 16);
parseInt("1111", 2);
parseInt("15\*3", 10);
parseInt("15e2", 10);
parseInt("15px", 10);
parseInt("12", 13);
```

Все следующие примеры возвращают **`NaN`**:

```js
parseInt("Hello", 8); // Не является числом
parseInt("546", 2); // Неверное число в двоичной системе счисления
```

Все следующие примеры возвращают **`-15`**:

```js
parseInt("-F", 16);
parseInt("-0F", 16);
parseInt("-0XF", 16);
parseInt(-15.1, 10);
parseInt(" -17", 8);
parseInt(" -15", 10);
parseInt("-1111", 2);
parseInt("-15e1", 10);
parseInt("-12", 13);
```

Все следующие примеры возвращают **`4`**:

```js
parseInt(4.7, 10);
parseInt(4.7 \* 1e22, 10); // Очень большие числа становятся 4
parseInt(0.00000000000434, 10); // Очень маленькие числа становятся 4
```

Следующий пример возвращает **`224`**:

```js
parseInt("0e0", 16);
```

Восьмеричная интерпретация без указания системы счисления
---------------------------------------------------------

Хотя это не поощряется в спецификацией ECMAScript 3 и запрещено в ECMAScript 5, многие реализации интерпретируют числовую строку, начинающуюся с `0`, как восьмеричную. Следующий пример может иметь как восьмеричный, так и десятичный результат. **Чтобы избежать непредвиденного результата, всегда указывайте основание системы счисления.**

```js
parseInt("0e0"); // 0
parseInt("08"); // 0, '8' не является цифрой в восьмеричной системе.
```

### ECMAScript 5 устраняет восьмеричную интерпретацию

Спецификация ECMAScript 5 функции `parseInt` больше не разрешает трактовать в восьмеричной системе счисления строки, начинающиеся с `0`. ECMAScript 5 провозглашает:

Функция `parseInt` производит целочисленное значение в результате интерпретации содержимого строкового аргумента в соответствии с указанным основанием системы счисления. Пробел в начале строки не учитывается. Если основание системы счисления не определено или равно `0`, оно считается равным `10`, за исключением случаев, когда строка начинается с пар символов `0x` или `0X`: тогда за основание принимается 16. Если основанием системы счисления указано `16`, число также может начинаться с пар символов `0x` или `0X`.

В этом ECMAScript 5 расходится со спецификацией ECMAScript 3, в которой восьмеричная интерпретация не поощрялась, но и не была запрещена.

Поскольку на момент 2013 года описанное выше поведение было применено не во всех реализациях, а поддержка старых браузеров является необходимой, **всегда указывайте основание системы счисления.**

Более строгая функция интерпретации
-----------------------------------

Иногда необходим более строгий способ интерпретации целочисленных значений. В этом могут помочь регулярные выражения:

```js
var filterInt = function (value) {
  if (/^(\-|\+)?([0-9]+|Infinity)$/.test(value)) return Number(value);
  return NaN;
};

console.log(filterInt("421")); // 421
console.log(filterInt("-421")); // -421
console.log(filterInt("+421")); // 421
console.log(filterInt("Infinity")); // Infinity
console.log(filterInt("421e+0")); // NaN
console.log(filterInt("421hop")); // NaN
console.log(filterInt("hop1.61803398875")); // NaN
console.log(filterInt("1.61803398875")); // NaN
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-parseint-string-radix |

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

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

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

* `parseFloat()`
* `Number.parseFloat()`
* `Number.parseInt()`
* `isNaN()`
* `Number.toString()`
* `Object.valueOf`


SharedArrayBuffer - JavaScript

SharedArrayBuffer
=================

Объект **`SharedArrayBuffer`** подобен ArrayBuffer, то есть это буфер фиксированной длины, использующийся для хранения любых бинарных данных. Главное отличие `SharedArrayBuffer` от `ArrayBuffer` заключается в том, что он используется для создания разделяемой области памяти. В отличие от `ArrayBuffer` `SharedArrayBuffer` не может быть откреплён от соответствующей ему области памяти.

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

### Выделение и совместное использование памяти

Для совместного использования памяти с помощью объекта `SharedArrayBuffer` между одним агентом в кластере и другим (агентом может быть как основная программа страницы сайта, так и один из её веб-воркеров) используются `postMessage` и алгоритм структурированного клонирования.

Алгоритм структурированного клонирования принимает `SharedArrayBuffers` и `TypedArrays`, отображённый в `SharedArrayBuffers`. В обоих случаях объект `SharedArrayBuffer` передаётся получателю, что приводит к появлению нового приватного объекта SharedArrayBuffer внутри агента-получателя (так же как для `ArrayBuffer`). Оба объекта `SharedArrayBuffer` ссылаются на один и тот же блок общих данных, и побочный эффект, изменяющий блок данных в одном из агентов, в итоге проявится в другом агенте.

```js
var sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
```

### Обновление и синхронизация разделяемой памяти с помощью атомарных операций

Разделяемую память можно создавать и изменять одновременно в воркерах или основном потоке. В зависимости от системы (ЦПУ, ОС, браузера), распространение изменений по всем контекстам может занять некоторое время. Для синхронизации необходимы атомарные операции .

### API, принимающие объекты `SharedArrayBuffer`

* `WebGLRenderingContext.bufferData()` (en-US)
* `WebGLRenderingContext.bufferSubData()` (en-US)
* `WebGL2RenderingContext.getBufferSubData()` (en-US)
### Требования безопасности

Разделяемая память и таймеры высокого разрешения были отключены в начале 2018 года из-за атаки Spectre. В 2020 году был стандартизирован новый, безопасный подход, чтобы включить разделяемую память обратно.

Основное требование — ваш документ должен находиться в безопасном контексте (en-US).

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

* `Cross-Origin-Opener-Policy` (en-US) со значением `same-origin`` (защищает ваш источник от атаки)
* `Cross-Origin-Embedder-Policy` (en-US) со значением `require-corp` или `credentialless` (защищает жертв от вашего источника)

Чтобы проверить, что изоляция от других источников прошла успешно, протестируйте свойство `crossOriginIsolated` (en-US), доступное для контекстов окна и воркера:

```js
const myWorker = new Worker("worker.js");

if (crossOriginIsolated) {
  const buffer = new SharedArrayBuffer(16);
  myWorker.postMessage(buffer);
} else {
  const buffer = new ArrayBuffer(16);
  myWorker.postMessage(buffer);
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-sharedarraybuffer-objects |

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

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

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

* `Atomics`
* `ArrayBuffer`
* JavaScript typed arrays guide
* Web Workers
* Shared Memory – a brief tutorial in the TC39 ecmascript-sharedmem proposal
* A Taste of JavaScript's New Parallel Primitives on hacks.mozilla.org (2016)
* COOP and COEP explained by the Chrome team (2020)
* `Cross-Origin-Opener-Policy` (en-US)
* `Cross-Origin-Embedder-Policy` (en-US)
* `Cross-Origin-Resource-Policy` (en-US)
* `crossOriginIsolated` (en-US)
* SharedArrayBuffer updates in Android Chrome 88 and Desktop Chrome 92 on developer.chrome.com (2021)


URIError - JavaScript

URIError
========

Объект **`URIError`** представляет ошибку, возникающую при неправильном использовании глобальных функций обработки URI.

`URIError` является сериализуемым объектом (en-US), поэтому он может быть клонирован с помощью `structuredClone()` (en-US) или передан между воркерами с использованием `postMessage()`.

`URIError` является подклассом `Error`.

Конструктор
-----------

`URIError()` (en-US)

Создаёт новый объект `URIError`.

Свойства экземпляра
-------------------

*Также наследует свойства своего родителя `Error`*.

Эти свойства определены в `URIError.prototype` и есть у всех экземпляров `URIError`.

`URIError.prototype.constructor`

Функция-конструктор, создающая экземпляр объекта. Для экземпляров `URIError` начальным значением является конструктор `URIError` (en-US).

`URIError.prototype.name`

Представляет название типа ошибки. Начальным значением `URIError.prototype.name` является `"URIError"`.

Методы экземпляра
-----------------

*Наследует методы своего родителя `Error`*.

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

### Перехват `URIError`

```js
try {
  decodeURIComponent("%");
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message); // "malformed URI sequence"
  console.log(e.name); // "URIError"
  console.log(e.stack); // Стек ошибок
}
```

### Создание `URIError`

```js
try {
  throw new URIError("Привет");
} catch (e) {
  console.log(e instanceof URIError); // true
  console.log(e.message); // "Привет"
  console.log(e.name); // "URIError"
  console.log(e.stack); // Стек ошибок
}
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-native-error-types-used-in-this-standard-urierror |

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

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

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

* `Error`
* `decodeURI()`
* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`


Прокси - JavaScript

Прокси
======

Объект `Proxy` позволяет создать прокси для другого объекта, может перехватывать и переопределить основные операции для данного объекта.

Введение
--------

Прокси используются программистами для объявления расширенной семантики JavaScript объектов. Стандартная семантика реализована в движке JavaScript, который обычно написан на низкоуровневом языке программирования, например C++. Прокси позволяют программисту определить поведение объекта при помощи JavaScript. Другими словами они являются **инструментом метапрограммирования**.

**Примечание**: реализация прокси в SpiderMonkey является прототипом, в котором прокси API и семантика не стабильны. Также, реализация в SpiderMonkey может не соответствовать последней версии спецификации. Она может быть изменена в любой момент и предоставляется исключительно как экспериментальная функция. **Не полагайтесь на неё в производственном коде.**

Эта страница описывает новый API (называемый «непосредственным проксированием»), который является частью Firefox 18. Для просмотра старого API (Firefox 17 и ниже) посетите страницу описания старого прокси API.

Терминология
------------

механизм полного перехвата (или "intercession API")

Технический термин для этой функции.

прокси (proxy)

Объект, оборачивающий исходный объект.

обработчик (handler)

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

ловушки (traps)

Методы, которые предоставляют доступ к свойствам. Это аналогично концепции ловушек в операционных системах.

цель (target)

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

Прокси
------

Прокси - это новые объекты; невозможно выполнить "проксирование" существующего объекта. Пример создания прокси:

```js
var p = new Proxy(target, handler);
```

Где:

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

Все ловушки опциональны. В случае, если ловушка не задана, то стандартным поведением будет перенаправление операции к объекту-цели.

| JavaScript-код | Метод обработчика | Описание |
| --- | --- | --- |
| `Object.getOwnPropertyDescriptor(proxy, name)` | `getOwnPropertyDescriptor function(target, name) -> PropertyDescriptor | undefined` | Должен возвращать верный объект-описание свойства или `undefined`, чтобы показать, что свойство с именем `name` существует в эмулируемом объекте. |
| `Object.getOwnPropertyNames(proxy)` `Object.getOwnPropertySymbols(proxy)` `Object.keys(proxy)` | `ownKeys function(target) -> [string | symbol]` | Возвращает массив всех собственных (не унаследованных) имён свойств эмулируемого объекта. |
| `Object.defineProperty(proxy,name,pd)` | `defineProperty function(target, name, propertyDescriptor) -> any` | Задаёт новое свойство, атрибуты которого определяются предоставленным `propertyDescriptor`. Возвращаемое значение метода игнорируется. |
| `delete proxy.name` | `deleteProperty function(target, name) -> boolean` | Удаляет именованное свойство из прокси. Возвращает `true` в случае успешного удаления свойства `name`. |
| `Object.preventExtensions(proxy)` | `preventExtensions function(target) -> boolean` | Делает объект нерасширяемым. Возвращает `true` при успешном выполнении. |
| `name in proxy` | `has function(target, name) -> boolean` |  |
| `proxy.name` (in the context of "getting the value") `receiver.name` (if `receiver` inherits from a proxy and does not override `name`) | `get function(target, name, receiver) -> any` | `receiver` — это прокси или объект, унаследованный от прокси. |
| `proxy.name = val` (in the context of "setting the value") `receiver.name = val` (if `receiver` inherits from a proxy and does not override `name`) | `set function(target, name, val, receiver) -> boolean` | `receiver` — это прокси или объект, унаследованный от прокси. |
| `proxy(...args) proxy.apply(thisValue, args) proxy.call(thisValue, ...args)` | `apply function(target, thisValue, args) -> any` | `target` должен быть функцией. |
| `new proxy(...args)` | `construct function(target, args) -> object` | `target` должен быть функцией. |

Инварианты
----------

Несмотря на то, что прокси предоставляют много возможностей пользователям, некоторые операции не перехватываются для сохранения постоянства языка:

* Простой и строгий оператор равенства (`==`, `===`) не перехватывается. `p1 === p2` равны, только если `p1` и `p2` ссылаются на один и тот же прокси.
* Текущая реализация `Object.getPrototypeOf(proxy)` всегда возвращает `Object.getPrototypeOf(target)`, потому что в ES2015 перехватчик getPrototypeOf пока не реализован.
* `typeof proxy` всегда возвращает `typeof target`. В частности, `proxy` может быть использован как функция только если `target` является функцией.
* `Array.isArray(proxy)` всегда возвращает `Array.isArray(target)`.
* `Object.prototype.toString.call(proxy)` всегда возвращает `Object.prototype.toString.call(target)`, потому что в ES2015 перехватчик Symbol.toStringTag пока не реализован.
Примеры
-------

### Простой пример

Объект, возвращающий значение `37`, в случае отсутствия свойства с указанным именем:

```js
var handler = {
  get: function (target, name) {
    return name in target ? target[name] : 37;
  },
};

var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log("c" in p, p.c); // false, 37
```

### Перенаправляющий прокси

В данном примере мы используем JavaScript объект, к которому наш прокси направляет все запросы:

```js
var target = {};
var p = new Proxy(target, {});

p.a = 37; // операция перенаправлена прокси

console.log(target.a); // 37. Операция была успешно перенаправлена
```

### Проверка

При помощи `Proxy` вы можете легко проверять передаваемые объекту значения:

```js
let validator = {
  set: function (obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }

    // Стандартное сохранение значения
    obj[prop] = value;

    // Обозначить успех
    return true;
  },
};

let person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = "young"; // Вызовет исключение
person.age = 300; // Вызовет исключение
```

### Дополнение конструктора

Функция прокси может легко дополнить конструктор новым:

```js
function extend(sup, base) {
  var descriptor = Object.getOwnPropertyDescriptor(
    base.prototype,
    "constructor",
  );

  const prototype = { ...base.prototype };

  base.prototype = Object.create(sup.prototype);
  base.prototype = Object.assign(base.prototype, prototype);

  var handler = {
    construct: function (target, args) {
      var obj = Object.create(base.prototype);
      this.apply(target, obj, args);
      return obj;
    },
    apply: function (target, that, args) {
      sup.apply(that, args);
      base.apply(that, args);
    },
  };
  var proxy = new Proxy(base, handler);
  descriptor.value = proxy;
  Object.defineProperty(base.prototype, "constructor", descriptor);
  return proxy;
}

var Person = function (name) {
  this.name = name;
};

var Boy = extend(Person, function (name, age) {
  this.age = age;
});

Boy.prototype.sex = "M";

var Peter = new Boy("Peter", 13);
console.log(Peter.sex); // "M"
console.log(Peter.name); // "Peter"
console.log(Peter.age); // 13
```

### Манипуляция DOM элементами

Иногда возникает необходимость переключить атрибут или имя класса у двух разных элементов:

```js
let view = new Proxy(
  {
    selected: null,
  },
  {
    set: function (obj, prop, newval) {
      let oldval = obj[prop];

      if (prop === "selected") {
        if (oldval) {
          oldval.setAttribute("aria-selected", "false");
        }
        if (newval) {
          newval.setAttribute("aria-selected", "true");
        }
      }

      // Стандартное сохранение значения
      obj[prop] = newval;
    },
  },
);

let i1 = (view.selected = document.getElementById("item-1"));
console.log(i1.getAttribute("aria-selected")); // 'true'

let i2 = (view.selected = document.getElementById("item-2"));
console.log(i1.getAttribute("aria-selected")); // 'false'
console.log(i2.getAttribute("aria-selected")); // 'true'
```

### Изменение значений и дополнительные свойства

Прокси объект `products` проверяет передаваемые значения и преобразует их в массив в случае необходимости. Объект также поддерживает дополнительное свойство `latestBrowser` на чтение и запись.

```js
let products = new Proxy(
  {
    browsers: ["Internet Explorer", "Netscape"],
  },
  {
    get: function (obj, prop) {
      // Дополнительное свойство
      if (prop === "latestBrowser") {
        return obj.browsers[obj.browsers.length - 1];
      }

      // Стандартный возврат значения
      return obj[prop];
    },
    set: function (obj, prop, value) {
      // Дополнительное свойство
      if (prop === "latestBrowser") {
        obj.browsers.push(value);
        return;
      }

      // Преобразование значения, если оно не массив
      if (typeof value === "string") {
        value = [value];
      }

      // Стандартное сохранение значения
      obj[prop] = value;
    },
  },
);

console.log(products.browsers); // ['Internet Explorer', 'Netscape']
products.browsers = "Firefox"; // передаётся как строка (по ошибке)
console.log(products.browsers); // ['Firefox'] <- проблем нет, значение - массив

products.latestBrowser = "Chrome";
console.log(products.browsers); // ['Firefox', 'Chrome']
console.log(products.latestBrowser); // 'Chrome'
```

### Поиск элемента массива по его свойству

Данный прокси расширяет массив дополнительными возможностями. Как вы видите, вы можете гибко "задавать" свойства без использования `Object.defineProperties` (en-US). Данный пример также может быть использован для поиска строки таблицы по её ячейке. В этом случае целью будет `table.rows` (en-US).

```js
let products = new Proxy(
  [
    { name: "Firefox", type: "browser" },
    { name: "SeaMonkey", type: "browser" },
    { name: "Thunderbird", type: "mailer" },
  ],
  {
    get: function (obj, prop) {
      // Стандартное возвращение значения; prop обычно является числом
      if (prop in obj) {
        return obj[prop];
      }

      // Получение количества продуктов; псевдоним products.length
      if (prop === "number") {
        return obj.length;
      }

      let result,
        types = {};

      for (let product of obj) {
        if (product.name === prop) {
          result = product;
        }
        if (types[product.type]) {
          types[product.type].push(product);
        } else {
          types[product.type] = [product];
        }
      }

      // Получение продукта по имени
      if (result) {
        return result;
      }

      // Получение продуктов по типу
      if (prop in types) {
        return types[prop];
      }

      // Получение типов продуктов
      if (prop === "types") {
        return Object.keys(types);
      }

      return undefined;
    },
  },
);

console.log(products[0]); // { name: 'Firefox', type: 'browser' }
console.log(products["Firefox"]); // { name: 'Firefox', type: 'browser' }
console.log(products["Chrome"]); // undefined
console.log(products.browser); // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }]
console.log(products.types); // ['browser', 'mailer']
console.log(products.number); // 3
```

### Пример использования всех перехватчиков

В данном примере, использующем все виды перехватчиков, мы попытаемся проксировать *не нативный* объект, который частично приспособлен для этого - `docCookies,` созданном в разделе "little framework" и опубликованном на странице `document.cookie` (en-US).

```js
/\*
 var docCookies = ... получить объект "docCookies" можно здесь:
 https://developer.mozilla.org/ru/docs/DOM/document.cookie#A\_little\_framework.3A\_a\_complete\_cookies\_reader.2Fwriter\_with\_full\_unicode\_support
\*/

var docCookies = new Proxy(docCookies, {
  get: function (oTarget, sKey) {
    return oTarget[sKey] || oTarget.getItem(sKey) || undefined;
  },
  set: function (oTarget, sKey, vValue) {
    if (sKey in oTarget) {
      return false;
    }
    return oTarget.setItem(sKey, vValue);
  },
  deleteProperty: function (oTarget, sKey) {
    if (sKey in oTarget) {
      return false;
    }
    return oTarget.removeItem(sKey);
  },
  enumerate: function (oTarget, sKey) {
    return oTarget.keys();
  },
  iterate: function (oTarget, sKey) {
    return oTarget.keys();
  },
  ownKeys: function (oTarget, sKey) {
    return oTarget.keys();
  },
  has: function (oTarget, sKey) {
    return sKey in oTarget || oTarget.hasItem(sKey);
  },
  hasOwn: function (oTarget, sKey) {
    return oTarget.hasItem(sKey);
  },
  defineProperty: function (oTarget, sKey, oDesc) {
    if (oDesc && "value" in oDesc) {
      oTarget.setItem(sKey, oDesc.value);
    }
    return oTarget;
  },
  getPropertyNames: function (oTarget) {
    return Object.getPropertyNames(oTarget).concat(oTarget.keys());
  },
  getOwnPropertyNames: function (oTarget) {
    return Object.getOwnPropertyNames(oTarget).concat(oTarget.keys());
  },
  getPropertyDescriptor: function (oTarget, sKey) {
    var vValue = oTarget[sKey] || oTarget.getItem(sKey);
    return vValue
      ? {
          value: vValue,
          writable: true,
          enumerable: true,
          configurable: false,
        }
      : undefined;
  },
  getOwnPropertyDescriptor: function (oTarget, sKey) {
    var vValue = oTarget.getItem(sKey);
    return vValue
      ? {
          value: vValue,
          writable: true,
          enumerable: true,
          configurable: false,
        }
      : undefined;
  },
  fix: function (oTarget) {
    return "not implemented yet!";
  },
});

/\* Проверка cookies \*/

alert((docCookies.my_cookie1 = "First value"));
alert(docCookies.getItem("my\_cookie1"));

docCookies.setItem("my\_cookie1", "Changed value");
alert(docCookies.my_cookie1);
```

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

* "Proxies are awesome" презентация Brendan Eich на JSConf (слайды)
* Страница предложения ECMAScript Harmony Proxy и страница ECMAScript Harmony proxy semantics
* Руководство по прокси
* Старая страница Proxy API
* `Object.watch` - не стандартная возможность, поддерживается только в движке Gecko.
Лицензионные примечания
-----------------------

Некоторое содержимое (текст, примеры) данной страницы было скопировано или адаптировано со страниц вики ECMAScript, имеющей лицензию CC 2.0 BY-NC-SA


Float32Array - JavaScript

Float32Array
============

Объект **`Float32Array`** представляет типизированный массив 32-битных чисел с плавающей запятой (соответствует типу float в языке C) с платформо-зависимым порядком байт. Если необходим контроль за порядком байт, то вместо этого объекта используйте [`DataView`]](/ru/docs/Web/JavaScript/Reference/Global\_Objects/DataView) Содержимое инициализируется значением `0`. Создав экземпляр **`Float32Array`**, можно получить доступ к элементам массива, используя методы объекта или стандартный синтаксис доступа к элементу массива по его индексу (с помощью скобочной нотации - квадратные скобки).

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

new Float32Array(); // new in ES2017
new Float32Array(length);
new Float32Array(typedArray);
new Float32Array(object);
new Float32Array(buffer [, byteOffset [, length]]);
```

Для более подробной информации о синтаксисе конструктора и его параметрах смотрите *TypedArray*.

Свойства
--------

`Float32Array.BYTES_PER_ELEMENT`

Возвращает число, соответствующее размеру элемента массива в байтах. Для `Float32Array` это `4`.

Float32Array.length

Статическое свойство "длина" со значением 0. Если хотите получить актуальную длину массива (число элементов) используйте `Float32Array.prototype.length` (en-US).

`Float32Array.name` (en-US)

Возвращает строковое представление названия конструктора. В данном случае `Float32Array` вернёт `"Float32Array"`.

`Float32Array.prototype` (en-US)

Прототип объекта `TypedArray`.

Методы
------

`Float32Array.from()` (en-US)

Создаёт новый `Float32Array` из массивоподобного или итерируемого объекта. Смотрите также `Array.from()`.

`Float32Array.of()` (en-US)

Создаёт новый `Float32Array` с заданным числом элементов. Смотрите также `Array.of()`.

`Float32Array` prototype
------------------------

``Любые `Float32Array` объекты наследуются от `%TypedArray%.prototype` (en-US).

### Свойства

`Float32Array.prototype.constructor`

Возвращает функцию, которая создаёт экземпляр прототипа. В данном случае это конструктор `Float32Array`.

`Float32Array.prototype.buffer` (en-US) Только для чтения

Возвращает `ArrayBuffer`, на который ссылается `Float32Array.` Автоматически изменяется при операциях над массивом и поэтому доступен **только для чтения**.

`Float32Array.prototype.byteLength` (en-US) Только для чтения

Возвращает длину в байтах для `Float32Array` с начала его `ArrayBuffer`. Автоматически изменяется при операциях над массивом и поэтому доступен **только для чтения**.

`Float32Array.prototype.byteOffset` (en-US) Только для чтения

Возвращает смещение (в байтах) `Float32Array` относительно начала `ArrayBuffer`. Автоматически изменяется при операциях над массивом и поэтому доступен **только для чтения**.

`Float32Array.prototype.length` (en-US) Только для чтения

Возвращает число элементов, хранящихся в `Float32Array`. Автоматически изменяется при операциях над массивом и поэтому доступен **только для чтения**.

### Методы

`Float32Array.prototype.copyWithin()` (en-US)

Копирует последовательность элементов в массив. Смотрите также `Array.prototype.copyWithin()`.

`Float32Array.prototype.entries()` (en-US)

Возвращает новый объект `Array Iterator`, который содержит пары ключ-значение для каждого элемента в массиве. Смотрите также `Array.prototype.entries()`.

`Float32Array.prototype.every()` (en-US)

Проверяет, что все элементы в массиве соответствуют условию. Смотрите также `Array.prototype.every()`.

`Float32Array.prototype.fill()` (en-US)

Заполняет весь массив от начального до последнего индекса одинаковыми элементами. Смотрите также `Array.prototype.fill()`.

`Float32Array.prototype.filter()` (en-US)

Возвращает новый массив со всеми элементами удовлетворяющей условию. Смотрите также `Array.prototype.filter()`.

`Float32Array.prototype.find()` (en-US)

Возвращает найденное значение в массиве, если найден элемент соответствующий условию, в противном случае возвращает `undefined`. Смотрите также `Array.prototype.find()`.

`Float32Array.prototype.findIndex()` (en-US)

Возвращает индекс найденного значения в массиве, если найден элемент соответствующий условию, в противном случае возвращает `-1`. Смотрите также `Array.prototype.findIndex()`.

`Float32Array.prototype.forEach()` (en-US)

Вызывает функцию для каждого элемента в массиве. Смотрите также `Array.prototype.forEach()`.

`Float32Array.prototype.includes()` (en-US)
Экспериментальная возможность

Проверяет что массив включает себя элемент, возвращает соответственно true или false. Смотрите также `Array.prototype.includes()`.

`Float32Array.prototype.indexOf()` (en-US)

Возвращает индекс элемента соответствующего условию (равен значению), в противном случае возвращает -1. Смотрите также `Array.prototype.indexOf()`.

`Float32Array.prototype.join()`

Объединяет элементы массива в строку. Смотрите также `Array.prototype.join()`.

`Float32Array.prototype.keys()` (en-US)

Возвращает новый `Array Iterator,` который содержит ключи элементов в массиве. Смотрите также `Array.prototype.keys()`.

`Float32Array.prototype.lastIndexOf()` (en-US)

Возвращает последний найденный индекс соответствующий искомому значению, в противном случае возвращает - 1. Смотрите также `Array.prototype.lastIndexOf()`.

`Float32Array.prototype.map()` (en-US)

Возвращает новый массив с результатом применения функции к каждому элементу в этом массиве. Смотрите также `Array.prototype.map()`.

`Float32Array.prototype.move()`
Non-standard
 Не реализовано

Нестандартизированная версия `Float32Array.prototype.copyWithin()` (en-US).

`Float32Array.prototype.reduce()` (en-US)

Применяет функцию к каждому элементу в массиве (слева-направо) и накапливает результат в переменной. Смотрите также `Array.prototype.reduce()`.

`Float32Array.prototype.reduceRight()` (en-US)

Применяет функцию к каждому элементу в массиве (справа-налево) и накапливает результат в переменной. Смотрите также `Array.prototype.reduceRight()`.

`Float32Array.prototype.reverse()` (en-US)

Переставляет элементы массива в обратном порядке - первый становится последним и так далее. Смотрите также `Array.prototype.reverse()`.

`Float32Array.prototype.set()`

Сохраняет значения в массиве.

`Float32Array.prototype.slice()` (en-US)

Выделяет часть массива и возвращает новый с этими значениями. Смотрите также `Array.prototype.slice()`.

`Float32Array.prototype.some()` (en-US)

Возвращает true если хотя бы один элемент удовлетворяет условию. Смотрите также `Array.prototype.some()`.

`Float32Array.prototype.sort()` (en-US)

Сортирует элементы массива по порядку и возвращает этот массив. Смотрите также `Array.prototype.sort()`.

`Float32Array.prototype.subarray()` (en-US)

`Возваращает новый Float32Array` с заданного начального по конечный индекс.

`Float32Array.prototype.values()` (en-US)

Возвращает новый объект `Array Iterator` который содержит значения всех элементов в массиве. Смотрите также `Array.prototype.values()`.

`Float32Array.prototype.toLocaleString()` (en-US)

Возвращает локализированную строку представляющую массив и его элементы. Смотрите также `Array.prototype.toLocaleString()`.

`Float32Array.prototype.toString()` (en-US)

Возвращает строку представляющую массив и его элементы. Смотрите также `Array.prototype.toString()`.

`Float32Array.prototype[@@iterator]()` (en-US)

`Возвращает новый объект Array Iterator который содержит значения всех элементов в массиве.`

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

Разные способы создания `Float32Array`:

```js
// Используя указание длины
var float32 = new Float32Array(2);
float32[0] = 42;
console.log(float32[0]); // 42
console.log(float32.length); // 2
console.log(float32.BYTES\_PER\_ELEMENT); // 4

// Из массива
var arr = new Float32Array([21, 31]);
console.log(arr[1]); // 31

// Из другого TypedArray
var x = new Float32Array([21, 31]);
var y = new Float32Array(x);
console.log(y[0]); // 21

// Из другого ArrayBuffer
var buffer = new ArrayBuffer(16);
var z = new Float32Array(buffer, 0, 4);

// Из итератора
var iterable = (function\* () {
  yield\* [1, 2, 3];
})();
var float32 = new Float32Array(iterable);
// Float32Array[1, 2, 3]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # table-49 |

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

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

Примечания по совместимости
---------------------------

Начиная с ECMAScript 2015 (ES6), `Float32Array` конструктор обязательно должен вызываться с ключевым словом `new`. Вызов `Float32Array` конструктора как функцию приведёт к исключению `TypeError`.

```js
var dv = Float32Array([1, 2, 3]);
// TypeError: calling a builtin Float32Array constructor
// without new is forbidden
```

```js
var dv = new Float32Array([1, 2, 3]);
```

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

* JavaScript typed arrays
* `ArrayBuffer`
* `DataView`


Reflect - JavaScript

Reflect
=======

**Reflect** - это встроенный объект, который предоставляет методы для перехватываемых JavaScript операций. Эти методы аналогичны методам proxy handler (en-US). `Reflect` - это не функциональный, а простой объект, он не является сконструированным.

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

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

Методы
------

Объект `Reflect` обеспечивает работу статических функций, называющиеся так же, как методы proxy handler (en-US). Некоторые из этих методов - те же, что и соответствующие им методы класса `Object`.

`Reflect.apply()`

Вызывает целевую функцию с аргументами, переданными в параметре `args`. Смотрите также `Function.prototype.apply()`.

`Reflect.construct()`

Оператор `new` как функция. Аналогично `new target(...args)`. Также предоставляет возможность определить другой прототип.

`Reflect.defineProperty()`

Похож на `Object.defineProperty()`. Возвращает `Boolean`.

`Reflect.deleteProperty()`

Оператор `delete` как функция. Аналогично `delete target[name]`.

`Reflect.enumerate()`

Похож на цикл `for...in`. Возвращает итератор с собственными перечисляемыми и наследуемыми свойствами целевого объекта.

`Reflect.get()`

Функция, которая возвращает значение свойств.

`Reflect.getOwnPropertyDescriptor()` (en-US)

Аналогично `Object.getOwnPropertyDescriptor()`. Возвращает дескриптор указанного свойства если присутствует в объекте, иначе `undefined`.

`Reflect.getPrototypeOf()` (en-US)

Аналогично `Object.getPrototypeOf()`.

`Reflect.has()` (en-US)

Оператор `in` как функция. Возвращает значение `Boolean` в зависимости от факта наличия собственного или наследованного свойства.

`Reflect.isExtensible()` (en-US)

Аналогично `Object.isExtensible()`.

`Reflect.ownKeys()`

Возвращает массив строк с именами собственных (не наследованных) свойств.

`Reflect.preventExtensions()` (en-US)

Аналогично `Object.preventExtensions()`. Возвращает `Boolean`.

`Reflect.set()` (en-US)

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

`Reflect.setPrototypeOf()` (en-US)

Функция, присваивающая прототип целевому объекту.

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

### Проверка наличия конкретных свойств у объекта

```js
const duck = {
  name: "Maurice",
  color: "white",
  greeting: function () {
    console.log(`Quaaaack! My name is ${this.name}`);
  },
};

Reflect.has(duck, "color");
// true
Reflect.has(duck, "haircut");
// false
```

### Возврат собственных ключей объекта

```js
Reflect.ownKeys(duck);
// [ "name", "color", "greeting" ]
```

### Добавление нового свойства в объект

```js
Reflect.set(duck, "eyes", "black");
// вернётся "true" если вызов успешен
// объект "duck" теперь содержит свойство "eyes" со значением "black"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-reflect-object |

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

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

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

* Глобальный объект `Proxy`.
* Объект `handler` (en-US).