201 Created - HTTP

201 Created
===========

HTTP **`201 Created`** Код ответа об успешном статусе указывает, что запрос выполнен успешно и привёл к созданию ресурса. Новый ресурс эффективно создаётся до отправки этого ответа. И новый ресурс возвращается в теле сообщения, его местоположение представляет собой либо URL-адрес запроса, либо содержимое заголовка `Location.`

Общим случаем использования этого кода состояния является результат `POST` запроса.

Статус
------
```

201 Created
```

Технические характеристики
--------------------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.3.2: 201 Created | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* HTTP request methods


429 Too Many Requests - HTTP

429 Too Many Requests
=====================

HTTP **`429 Too Many Requests`** код ответа указывает, что пользователь отправил слишком много запросов за последнее время ("ограничение скорости" или "rate limiting" ).

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

Статус
------
```

429 Too Many Requests
```

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

HTTP/1.1 429 Too Many Requests
Content-Type: text/html
Retry-After: 3600
```

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

| Спецификация | Название |
| --- | --- |
| RFC 6585, раздел 4: 429 Too Many Requests | Additional HTTP Status Codes |

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

* `Retry-After`
* 429 Too Many Requests


303 See Other - HTTP

303 See Other
=============

HTTP код перенаправления **`303 See Other`** обычно отправляется в результате `PUT` или `POST` запроса и указывает, что перенаправление производится не на новый (только что загруженный) ресурс, а на другую страницу, например, страницу подтверждения или страницу с результатами загрузки. Метод, используемый для отображения страницы, на которую производится перенаправление - всегда `GET`.

Статус
------
```

303 See Other
```

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

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

```http
POST /api/items/delete HTTP/1.1
Host: www.example.org
```

### Ответ сервера

```http
HTTP/1.1 303 See Other
Location: /confirmation
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.4.4: 303 See Other | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `302 Found`, временное перенаправление


404 Not Found - HTTP

404 Not Found
=============

Код ответа на ошибку HTTP **404 Not Found** указывает, что сервер не может найти запрошенный ресурс. Ссылки, ведущие к коду 404, часто называются сломанными или мёртвыми связями и приводят к ссылочной гнили.

Код статуса 404 не уточняет, отсутствует ли запрашиваемый ресурс временно или постоянно. Но если серверу известно, что указанный ресурс удалён навсегда, то вместо статуса 404 следует использовать `410` (Gone) .

Статус
------
```

404 Not Found
```

Пользовательские страницы ошибок
--------------------------------

Многие веб-сайты настраивают внешний вид страницы 404, чтобы быть более полезными для пользователя и давать рекомендации. Серверы Apache могут быть настроены с использованием файла **.htaccess** и фрагмента кода, например, такого, как этот.

```bash
ErrorDocument 404 /notfound.html
```

Вы можете взять MDN's 404 page в качестве вдохновения.

**Примечание:** Примечание: дизайн на 404 страницах - an endless source of inspiration, но имейте в виду, что в нем также существует a set of best practices, которые делают эти страницы полезными для пользователей веб-сайтов.

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.4: 404 Not Found | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `410`


502 Bad Gateway - HTTP

502 Bad Gateway
===============

HTTP серверный код ответа на ошибку **`502 Bad Gateway`** указывает, что сервер, действуя как шлюз или прокси, получил неверный ответ от восходящего сервера.

**Примечание:** Сетевой шлюз может ссылаться на разные вещи в сети, а ошибка 502 обычно не является чем-то, что вы можете исправить, но требует исправления веб-сервером или прокси, к которым вы пытаетесь получить доступ.

Статус
------
```

502 Bad Gateway
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.6.3: 502 Bad Gateway | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `504`
* 502 Bad Gateway


205 Reset Content - HTTP

205 Reset Content
=================

Статус ответа HTTP **`205 Reset Content`** сообщает клиенту об изменении вида документа, например, для очистки содержимого формы, сброса состояния холста или обновления пользовательского интерфейса.

Статус
------
```

205 Reset Content
```

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

| Specification | Title |
| --- | --- |
| RFC 7231, раздел 6.3.6: 205 Reset Content | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `204` No Content


410 Gone - HTTP

410 Gone
========

Код ошибки HTTP **`410 Gone`** указывает, что целевой ресурс больше недоступен на сервере происхождения и что это состояние, вероятно, будет постоянным.

Если вы не знаете, является это состояние временным или постоянным, вместо него следует использовать код статуса `404` .

**Примечание:** По умолчанию ответ 410 кешируется

Статус
------
```

410 Gone
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.9: 410 Gone | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `404`


408 Request Timeout - HTTP

408 Request Timeout
===================

HTTP **`408 Request Timeout`** означает, что сервер хотел бы отключить это неиспользуемое соединение. Он отправляется на незанятое соединение некоторыми серверами, *даже без какого-либо предыдущего запроса клиентом*

Сервер должен отправить заголовок `Connection` со значением «close» в ответ, поскольку **408** подразумевает, что сервер решил закрыть соединение, а не продолжать ждать.

Этот ответ используется гораздо больше, поскольку некоторые браузеры, такие как Chrome, Firefox 27+ или IE9, используют механизмы предварительного подключения HTTP для ускорения сёрфинга. Также обратите внимание, что некоторые серверы просто закрывают соединение без отправки этого сообщения.

Статус
------
```

408 Request Timeout
```

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

| Спецификация | Титул |
| --- | --- |
| RFC 7231, раздел 6.5.7: 408 Request Timeout | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Connection`
* `X-DNS-Prefetch-Control` (en-US)
* 408 Request Timeout


425 Too Early - HTTP

425 Too Early
=============

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

Код ответа протокола передачи гипертекста (HTTP) **`425 Too Early`** означает, что сервер не хочет рисковать обрабатывать запрос, который может быть воспроизведённым, поскольку это открывает возможность для атаки повторного воспроизведения.

Статус
------
```

425 Too Early
```

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

| Specification | Title |
| --- | --- |
| RFC 8470, раздел 5.2: 425: Early Data | Using Early Data in HTTP |

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

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


103 Early Hints - HTTP

103 Early Hints
===============

HTTP код **`103 Early Hints`** в первую очередь предназначен для использования с заголовком `Link` (en-US), чтобы клиент мог начать предварительную загрузку пока сервер готовит ответ.

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

103 Early Hints
```

Характеристики
--------------

| Характеристики | Статус | Комментарий |
| --- | --- | --- |
| RFC 8297: 103 Early Hints | IETF RFC | Начальное определение (Initial Definition) |

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

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

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

* `Link` (en-US)


414 URI Too Long - HTTP

414 URI Too Long
================

Код состояния HTTP **`414 URI Too Long`** указывает, что URI, запрошенный клиентом, длиннее, чем сервер готов интерпретировать.

Есть несколько редких условий, когда это может произойти:

* Когда клиент неправильно конвертировал `POST` запрос в `GET` запрос с длинной информацией запроса,
* Когда клиент спустился в цикл перенаправления (например, перенаправленный префикс URI, который указывает на суффикс самого себя),,
* Или когда сервер подвергается атаке со стороны клиента, пытающегося использовать потенциальные дыры в безопасности.
Статус
------
```

414 URI Too Long
```

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

| Спецификации | Название |
| --- | --- |
| RFC 7231, раздел 6.5.12: 414 URI Too Long | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* URI (en-US)


402 Payment Required - HTTP

402 Payment Required
====================

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

HTTP-ответ **`402 Payment Required`** это нестандартная ошибка клиента, зарезервированная для использования в будущем.

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

Статус
------
```

402 Payment Required
```

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

```bash
HTTP/1.1 402 Payment Required
Date: Wed, 21 Oct 2015 07:28:00 GMT
```

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

| Specification |
| --- |
| HTTP Semantics # status.402 |

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

Этот код состояния *зарезервирован*, но не определен. Браузеры не поддерживают его на данный момент и отображаются общую ошибку `4xx`.

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

* HTTP аутентификация


203 Non-Authoritative Information - HTTP

203 Non-Authoritative Information
=================================

"The HTTP **`203 Non-Authoritative Information`** Статус ответа указывает, что запрос был успешным, но прилагаемая полезная нагрузка была изменена с учётом ответа сервера`200` (`OK`) сервера происхождения с помощью преобразующего proxy.

"The `203"` ответ аналогичен значению `214` (en-US), значение "`Transformation Applied"`, кода `Warning` (en-US) имеет дополнительное преимущество, применимое к ответам с любым кодом состояния.

Статус
------
```

203 Non-Authoritative Information
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.3.4: 203 Non-Authoritative Information | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `200`
* Proxy server
* `Warning` (en-US)


451 Unavailable For Legal Reasons - HTTP

451 Unavailable For Legal Reasons
=================================

HTTP-код ответа **`451 Unavailable For Legal Reasons`** указывает, что пользователь запросил ресурс, который недоступен по юридическим причинам, например веб-страница, заблокированная из-за судебных исков.

Статус
------
```

451 Unavailable For Legal Reasons
```

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

Этот пример ответа берётся из IETF RFC (см. ниже) и содержит ссылку на Житие Брайана по Монти Пайтону.

Обратите внимание, что `Link` (en-US)также может содержать отношение a `rel="blocked-by"`, идентифицирующее объект, ответственный за недоступный ресурс, например имя человека или организации, которые предъявили законный запрос В результате чего удаление содержимого.
```

HTTP/1.1 451 Unavailable For Legal Reasons
Link: <https://spqr.example.org/legislatione>; rel="blocked-by"
Content-Type: text/html

<html>
<head><title>Unavailable For Legal Reasons</title></head>
<body>
<h1>Unavailable For Legal Reasons</h1>
<p>This request may not be serviced in the Roman Province
of Judea due to the Lex Julia Majestatis, which disallows
access to resources hosted on servers deemed to be
operated by the People's Front of Judea.</p>
</body>
</html>
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7725: 451 Unavailable For Legal Reasons | An HTTP Status Code to Report Legal Obstacles |

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

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


504 Gateway Timeout - HTTP

504 Gateway Timeout
===================

HTTP код **`504 Gateway Timeout`** , полученный в ответе, указывает на ошибку, что сервер, действуя как шлюз или прокси, не может получить ответ вовремя.

Сетевой шлюз может ссылаться на разные вещи в сети, а 504 error обычно не является чем-то, что вы можете исправить, но требует исправления веб-сервером или Прокси, к которым вы пытаетесь получить доступ.

Статус
------
```

504 Gateway Timeout
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.6.4: 504 Gateway Timeout | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `502`


301 Moved Permanently - HTTP

301 Moved Permanently
=====================

Код перенаправления **`301 Moved Permanently`** протокола передачи гипертекста (HTTP) показывает, что запрошенный ресурс был окончательно перемещён в URL, указанный в заголовке `Location` (en-US). Браузер в случае такого ответа перенаправляется на эту страницу, а поисковые системы обновляют свои ссылки на ресурс (говоря языком SEO, вес страницы переносится на новый URL-адрес).

Даже если спецификация требует, чтобы при выполнении перенаправления, метод и тело запроса не изменялись, не все пользовательские приложения обращают на это внимание, и вы все ещё можете столкнуться с программами имеющими этот баг. Именно поэтому код **301** рекомендуется только в качестве ответа на `GET` или `HEAD` запрос, а для `POST` рекомендуется код `308 Permanent Redirect`, так как он явно запрещает изменение метода запроса.

Статус
------
```

301 Moved Permanently
```

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

### Запрос клиента
```

GET /index.php HTTP/1.1
Host: www.example.org
```

### Ответ сервера
```

HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/index.asp
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.4.2: 301 Redirect Permanently | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `308 Permanent Redirect`
* `302 Found`, временное перенаправление


406 Not Acceptable - HTTP

406 Not Acceptable
==================

HyperText Transfer Protocol (HTTP) код ошибки клиента **`406 Not Acceptable`** означает, что сервер не может вернуть ответ, соответствующий списку допустимых значений, определённых в заголовках упреждающего согласования контента, и что сервер не желает вернуть представление контента по умолчанию.

Заголовки упреждающего согласования контента включают:

* `Accept`
* `Accept-Charset`
* `Accept-Encoding` (en-US)
* `Accept-Language`

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

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

Статус
------
```

406 Not Acceptable
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.6: 406 Not Acceptable | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `Accept`
* `Accept-Charset`
* `Accept-Encoding` (en-US)
* `Accept-Language`
* HTTP content negotiation


500 Internal Server Error - HTTP

500 Internal Server Error
=========================

Код ответа сервера **`500 Internal Server Error`** указывает на то, что сервер столкнулся с неожиданной ошибкой, которая помешала ему выполнить запрос.

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

Статус
------
```

500 Internal Server Error (Внутренняя ошибка сервера)
```

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

| Specification | Title |
| --- | --- |
| RFC 7231, раздел 6.6.1: 500 Internal Server Error | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

Дополнительная информация
-------------------------

* 500 Internal Server Error


412 Precondition Failed - HTTP

412 Precondition Failed
=======================

The HTTP **`412 Precondition Failed`** клиентский код ответа на ошибку указывает, что доступ к целевому ресурсу был отклонён. Это происходит с условными запросами на методы, отличные от `GET` или `HEAD`, когда условие определено `If-Unmodified-Since` или {HTTPHeader("If-None-Match")}} не выполняется. В этом случае запрос, обычно загрузка или изменение ресурса, не может быть выполнен, и этот ответ об ошибке отправляется обратно.

Статус
------
```

412 Precondition Failed
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7232, раздел 4.2: 412 Precondition Failed | Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests |

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

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

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

* `304`
* `If-Unmodified-Since`
* `If-None-Match` (en-US)
* `428`


416 Range Not Satisfiable - HTTP

416 Range Not Satisfiable
=========================

Код ошибки HTTP **416 Range Not Satisfiable** указывает, что сервер не может обслуживать запрошенные диапазоны. Наиболее вероятная причина заключается в том, что документ не содержит таких диапазонов или что значение `Range`, хотя и синтаксически корректно, не имеет смысла.

Сообщение ответа 416 содержит `Content-Range` (en-US), указывающий на неудовлетворённый диапазон (это `'*'`), за которым следуют `'/'` и размер текущего ресурса. Например: `Content-Range: bytes */12777`

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

Статус
------
```

416 Range Not Satisfiable
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7233, раздел 4.4: 416 Request Not Satisfiable | Hypertext Transfer Protocol (HTTP/1.1): Range Requests |

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

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

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

* `206` `Partial Content`
* `Content-Range` (en-US)
* `Range`


101 Switching Protocol - HTTP

101 Switching Protocol
======================

Код ответа протокола HTTP 101 Switching Protocol указывает протокол, который сервер переключает, используя клиентский запрос `Upgrade` (en-US).

Сервер отправляет заголовок ответа `Upgrade` (en-US), указывая протокол, на который он переключился.

Статус
------
```

101 Switching Protocol
```

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

Протоколы переключения могут использоваться с WebSockets.
```

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.2.2: 101 Switching Protocol | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* WebSockets
* `Upgrade` (en-US)
* `426` `Upgrade Required`


413 Payload Too Large - HTTP

413 Payload Too Large
=====================

Код HTTP **`413 Payload Too Large`** , указывает, что объект запроса больше, чем ограничения, определённые сервером; сервер может закрыть соединение или вернуть поле `Retry-After`.

Статус
------
```

413 Payload Too Large
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.11: 413 Payload Too Large | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Connection`
* `Retry-After`


422 Unprocessable Entity - HTTP

422 Unprocessable Entity
========================

Код состояния ответа HTTP **`422 Unprocessable Entity`** указывает, что сервер понимает тип содержимого в теле запроса и синтаксис запроса является правильным, но серверу не удалось обработать инструкции содержимого.

К примеру, эта ошибка может возникнуть, если тело запроса содержит хорошо сформированный (т.е. синтаксически корректный) XML-документ, но семантически ошибочные XML-инструкции.

**Предупреждение:** **Важно**: Клиент не должен повторять запрос повторно, т.е. без модификаций.

Статус
------
```

422 Unprocessable Entity
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 4918, раздел 11.2: 422 Unprocessable Entity | HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV) |


426 Upgrade Required - HTTP

426 Upgrade Required
====================

Код ответа на HTTP **`426 Upgrade Required`** указывает, что сервер отказывается выполнять запрос с использованием текущего протокола, но может захотеть сделать это после того, как клиент обновится до другого протокола.

Сервер отправляет `Upgrade` (en-US) с этим ответом, чтобы указать требуемый протокол (ы).

Статус
------
```

426 Upgrade Required
```

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

HTTP/1.1 426 Upgrade Required
Upgrade: HTTP/3.0
Connection: Upgrade
Content-Length: 53
Content-Type: text/plain

This service requires use of the HTTP/3.0 protocol
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.15: 426 Upgrade Required | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Upgrade` (en-US)
* `101` `Switching Protocol`


100 Continue - HTTP

100 Continue
============

Код ответа "HTTP **`100 Continue"`** на информационный статус указывает, что все до сих пор в порядке и что клиент должен продолжить запрос или игнорировать его, если он уже завершён.

Чтобы сервер проверял заголовки запроса, клиент должен отправить `Expect``:100-continue` в качестве заголовка в своём первоначальном запросе и получить код состояния `100-continue` в ответ перед отправкой тела.

Статус
------
```

100 Continue
```

Характеристики
--------------

| спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.2.1: 100 Continue | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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

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

* `Expect`
* `417`


417 Expectation Failed - HTTP

417 Expectation Failed
======================

Код ошибки HTTP **`417 Expectation Failed`** указывает на то, что ожидание, указанное в `Expect`, не может быть выполнено.

Дополнительную информацию смотрите в `Expect`.

Статус
------
```

417 Expectation Failed
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.14: 417 Expectation Failed | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Expect`


308 Permanent Redirect - HTTP

308 Permanent Redirect
======================

Код ответа HTTP **`308 Permanent Redirect"`** указывает, что запрошенный ресурс был окончательно перемещён на URL-адрес, указанный в заголовке `Location` (en-US). Браузер перенаправляется на эту страницу, а поисковые системы обновляют свои ссылки на ресурс (говоря языком SEO, «link-juice льётся на новый URL-адрес»).

Метод запроса и тело не изменяются, в отличие от ответа `301`, при котором иногда метод может быть неправильно изменён на `GET`.

**Примечание:** Некоторые веб-приложения могут использовать **308 Permanent Redirect** нестандартным образом и для других целей. Например, Google Drive использует ответ **308 Resume Incomplete**, чтобы указать клиенту, когда неполная загрузка остановилась (смотрите Perform a resumable download в документации Google Drive).

Статус
------

```http
308 Permanent Redirect
```

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

| Specification |
| --- |
| HTTP Semantics # status.308 |

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

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

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

* `301 Moved Permanently` — эквивалент кода ответа 308, способный изменять используемый метод, если он не является `GET`.
* `302 Found` — временное перенаправление.


511 Network Authentication Required - HTTP

511 Network Authentication Required
===================================

The HTTP **`511 Network Authentication Required`** код состояния ответа указывает, что клиент должен пройти аутентификацию, чтобы получить доступ к сети.

Этот статус не генерируется серверами происхождения, а путём перехвата прокси-серверов, которые контролируют доступ к сети.

Сетевые операторы иногда требуют некоторой аутентификации, принятия условий или другого взаимодействия с пользователем перед предоставлением доступа (например, в интернет-кафе или в аэропорту). Они часто идентифицируют клиентов, которые ещё не сделали этого, используя свой адрес Media Access Control (MAC).

Статус
------
```

511 Network Authentication Required
```

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

| Спецификация | Название |
| --- | --- |
| RFC 6585, раздел 6: 511 Network Authentication Required | Additional HTTP Status Codes |

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

* Proxy server


403 Forbidden - HTTP

403 Forbidden
=============

Код ответа на статус ошибки "HTTP 403 Forbidden" указывает, что сервер понял запрос, но отказывается его авторизовать.

Этот статус похож на `401`, но в этом случае повторная аутентификация не будет иметь никакого значения. Доступ запрещён и привязан к логике приложения (например, у пользователя не хватает прав доступа к запрашиваемому ресурсу).

Статус
------
```

403 Forbidden
```

Пример ответа
-------------
```

HTTP/1.1 403 Forbidden
Date: Wed, 21 Oct 2015 07:28:00 GMT
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.5.3: 403 Forbidden | HTTP/1.1: Semantics and Content |

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

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

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

* `401`
* 403 Forbidden


304 Not Modified - HTTP

304 Not Modified
================

Код "HTTP **304 Not Modified**" клиента указывает, что нет необходимости повторно передавать запрошенные ресурсы. Это неявное перенаправление на кешированный ресурс. Это происходит, когда метод safe, например `GET` или `HEAD` запрос или когда запрос является условным и использует `If-None-Match` (en-US) или `If-Modified-Since`.

Если эквивалентный ответ `200` `OK` включал `Cache-Control`, `Content-Location` (en-US), `Date`, `ETag`, `Expires` и `Vary`.

**Примечание:** Многие developer tools' network panels браузеров создают посторонние запросы, приводящие к 304 ответам, так что доступ к локальному кешу виден разработчикам.

Статус
------
```

304 Not Modified
```

Характеристики
--------------

| Спецификации | Название |
| --- | --- |
| RFC 7232, раздел 4.1: 304 Not Modified | Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests |

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

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

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

* `If-Modified-Since`
* `If-None-Match` (en-US)


202 Accepted - HTTP

202 Accepted
============

Код состояния ответа **`202 Accepted`** указывает, что запрос получен, но ещё не обработан. Это не является обязательным, что означает, что в *HTTP* невозможно передать более поздний асинхронный ответ, указывающий на результат обработки запроса. Он предназначен для случаев, когда другой процесс или сервер обрабатывает запрос или для пакетной обработки.

Статус
------
```

202 Accepted
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.3.3: 202 Accepted | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Accept`


505 HTTP Version Not Supported - HTTP

505 HTTP Version Not Supported
==============================

HTTP **`505 HTTP Version Not Supported`** код состояния ответа указывает, что версия HTTP, используемая в запросе, не поддерживается сервером.

Статус
------
```

505 HTTP Version Not Supported
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.6.6: 505 HTTP Version Not Supported | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `Upgrade` (en-US)


300 Multiple Choices - HTTP

300 Multiple Choices
====================

Код ответа на перенаправление "The HTTP **`300 Multiple Choices"`** указывает, что запрос имеет несколько возможных ответов. Пользователь-агент или пользователь должны выбрать один из них. Поскольку стандартного способа выбора одного из ответов нет, этот код ответа очень редко используется.

Если сервер имеет предпочтительный выбор, он должен создать `Location` (en-US).

Статус
------
```

300 Multiple Choices
```

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

См. это: w3.org page for a Multiple Choice response.

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.4.1: 300 Multiple Choices | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

* `301` `Moved Permanently`
* `302` `Found`, the temporary redirect
* `308` `Permanent Redirect`


407 Proxy Authentication Required - HTTP

407 Proxy Authentication Required
=================================

HTTP **`407 Proxy Authentication Required`** код ответа на ошибку клиента указывает, что запрос не был применён, поскольку он не имеет достоверных учётных данных для proxy server, который находится между браузером и сервером, который может получить доступ к запрашиваемому ресурсу..

Этот статус отправляется с `Proxy-Authenticate` (en-US), который содержит информацию о том, как правильно разрешить авторизацию.

Статус
------
```

407 Proxy Authentication Required
```

Пример ответа
-------------
```

HTTP/1.1 407 Proxy Authentication Required
Date: Wed, 21 Oct 2015 07:28:00 GMT
Proxy-Authenticate: Basic realm="Access to internal site"
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7235, раздел 3.2: 407 Proxy Authentication Required | HTTP/1.1: Authentication |

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

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

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

* HTTP authentication
* `WWW-Authenticate` (en-US)
* `Authorization`
* `Proxy-Authorization` (en-US)
* `Proxy-Authenticate` (en-US)
* `401`, `403`


501 Not Implemented - HTTP

501 Not Implemented
===================

The HTTP **`501 Not Implemented`** серверный код ответа на ошибку указывает, что метод запроса не поддерживается сервером и не может быть обработан. Единственными методами, которые необходимы серверам для поддержки (и, следовательно, не должны возвращать этот код), являются `GET` и `HEAD`.

Обратите внимание, что 501 error не является чем-то, что вы можете исправить, но требует исправления веб-сервером, к которому вы пытаетесь получить доступ.

**Примечание:** По умолчанию ответ 501 можно кешировать.

Статус
------
```

501 Not Implemented
```

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

| Спецификация | Название |
| --- | --- |
| RFC 7231, раздел 6.6.2: 501 Not Implemented | Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content |

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

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


206 Partial Content - HTTP

206 Partial Content
===================

"The HTTP **`206 Partial Content"`** код ответа на статус успешного указывает, что запрос преуспел, и тело содержит запрошенные диапазоны данных, как описано в `Range` запроса

Если существует только один диапазон, `Content-Type` всего ответа задаётся типом документа, а также `Content-Range` (en-US)

Если несколько диапазонов отправлены обратно, `Content-Type` задано значение **multipart/byteranges**, и каждый фрагмент охватывает один диапазон, `Content-Range` (en-US) и `Content-Type`, описывающий его.

Статус
------
```

206 Partial Content
```

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

Ответ, содержащий один диапазон:
```

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 2015 06:25:24 GMT
Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

... 26012 bytes of partial image data ...
```

Ответ, содержащий несколько диапазонов:
```

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 2015 06:25:24 GMT
Last-Modified: Wed, 15 Nov 2015 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=String_separator

--String_separator
Content-Type: application/pdf
Content-Range: bytes 234-639/8000

...the first range...
--String_separator
Content-Type: application/pdf
Content-Range: bytes 4590-7999/8000

...the second range
--String_separator--
```

Характеристики
--------------

| Спецификация | Название |
| --- | --- |
| RFC 7233, раздел 4.1: 206 Partial Content | Hypertext Transfer Protocol (HTTP/1.1): Range Requests |

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

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

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

* `If-Range` (en-US)
* `Range`
* `Content-Range` (en-US)
* `Content-Type`


Используемые по умолчанию значения заголовка Accept - HTTP

Используемые по умолчанию значения заголовка Accept
===================================================

В этой статье описывается, какие значения используются в HTTP-заголовке `Accept` по умолчанию в зависимости от конкретного запроса и версии браузера.

Значения по умолчанию
---------------------

Здесь приведены значения, которые отправляются, когда нет никакой уточняющей информации. Обратите внимание, что все браузеры добавляют MIME-тип `*/*`, чтобы были охвачены все возможные варианты. Обычно значения имеют такой вид, когда запросы выполняются через адресную строку или через HTML-элемент `<a>`.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` (начиная с Firefox 66) `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8` (в Firefox 65) `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` (в более ранних версиях) | В Firefox до версии 65 включительно значение можно изменить с помощью параметра `network.http.accept.default` (см. исходный код). |
| Safari, Chrome | `text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8` | исходный код |
| Safari 5 | `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` | Значение улучшено по сравнению с прежними вариантами заголовка `Accept`: MIME-тип `image/png` уже не указывается как более приоритетный, чем `text/html`. |
| Internet Explorer 8 | `image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */*` | См. запись IE and the Accept Header в блоге MSDN под названием IEInternals. |
| Edge | `text/html, application/xhtml+xml, image/jxr, */*` |  |
| Opera | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` |  |

Значения для изображений
------------------------

Если запрашивается изображение, например через HTML-элемент `<img>`, агент пользователя часто задаёт уточнённый список подходящих MIME-типов.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox | `image/webp,*/*` (начиная с Firefox 65) `*/*` (начиная с Firefox 47) `image/png,image/*;q=0.8,*/*;q=0.5` (в более ранних версиях) | Значение можно изменить с помощью параметра `image.http.accept`. исходный код |
| Safari | `*/*` |  |
| Chrome | `image/webp,image/apng,image/*,*/*;q=0.8` | исходный код |
| Internet Explorer до версии 8 включительно | `*/*` | См. запись IE and the Accept Header в блоге MSDN под названием IEInternals. |
| Internet Explorer 9 | `image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5` | См. запись Fiddler is better with Internet Explorer 9 в блоге MSDN под названием IEInternals. |

Значения для видео
------------------

Если запрашивается видео через HTML-элемент `<video>`, в большинстве браузеров используется уточнённое значение.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox до версии 3.6 | *Не поддерживается для элемента `<video>`.* |  |
| Firefox начиная с версии 3.6 | `video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5` | См. страницу ошибки 489071. исходный код |
| Chrome | `*/*` | исходный код |
| Internet Explorer до версии 8 включительно | *Не поддерживается для элемента `<video>`*. |  |

Значения для аудиофайлов
------------------------

Если запрашивается аудиофайл, например через HTML-элемент `<audio>`, в большинстве браузеров используется уточнённое значение.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox начиная с версии 3.6 | `audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5` | См. страницу ошибки 489071. исходный код |
| Safari, Chrome | `*/*` | исходный код |
| Internet Explorer до версии 8 включительно | *Не поддерживается для элемента `<audio>`.* |  |
| Internet Explorer 9 | ? |  |

Значения для скриптов
---------------------

Если запрашивается скрипт, например через HTML-элемент `<script>`, в некоторых браузерах используется уточнённое значение.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox | `*/*` | См. страницу ошибки 170789. |
| Safari, Chrome | `*/*` | исходный код |
| Internet Explorer до версии 8 включительно | `*/*` | См. запись IE and the Accept Header в блоге MSDN под названием IEInternals. |
| Internet Explorer 9 | `application/javascript, */*;q=0.8` | См. запись Fiddler is better with Internet Explorer 9 в блоге MSDN под названием IEInternals. |

Значения для таблиц стилей CSS
------------------------------

Если запрашивается таблица стилей CSS через HTML-элемент `<link rel="stylesheet">`, в большинстве браузеров используется уточнённое значение.

| Агент пользователя | Значение | Комментарий |
| --- | --- | --- |
| Firefox 4 | `text/css,*/*;q=0.1` | См. страницу ошибки 170789. исходный код |
| Internet Explorer до версии 8 включительно | `*/*` | См. запись IE and the Accept Header в блоге MSDN под названием IEInternals. |
| Internet Explorer 9 | `text/css` | См. запись Fiddler is better with Internet Explorer 9 в блоге MSDN под названием IEInternals. |
| Safari, Chrome | `text/css,*/*;q=0.1` | исходный код |
| Opera 11.10 | `text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1` |  |
| Konqueror 4.6 | `text/css,*/*;q=0.1` |  |


Обзор JavaScript - JavaScript

Обзор JavaScript
================

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

Если HTML определяет структуру и контент веб-страницы, а CSS задаёт формат и внешний вид, то JavaScript добавляет интерактивность и создаёт богатые веб-приложения.

Однако, под общим термином "JavaScript", в контексте веб-браузера, понимаются несколько очень разных вещей. Одна из них - это базовый язык программирования (ECMAScript), а другая - коллекция Web APIs, включая DOM (Объектно-ориентированная модель документа).

JavaScript, базовый язык программирования (ECMAScript)
------------------------------------------------------

Базовый язык JavaScript стандартизирован комитетом ECMA TC-39 как язык программирования под названием ECMAScript (en-US).

Базовый язык также используется в не-браузерном окружении, например, в node.js.

### Что попадает под понятие ECMAScript?

Кроме прочего, ECMAScript (en-US) определяет:

* Синтаксис языка (правила парсинга, ключевые слова, порядок выполнения, инициализацию объекта литерала...)
* Механизм обработки ошибок (исключения, try/catch оператор,возможность создавать новые типы ошибок)
* Типы данных (логические, числа, строки, функции, объекты...)
* Глобальный объект. В браузерах глобальным объектом является `window`, но ECMAscript определяет только те APIs, которые не являются специфическими для браузера, как `parseInt`, `parseFloat`, `decodeURI`, `encodeURI`...
* Механизм прототипного наследования
* Встроенные объекты и функции (JSON, Math, Array.prototype методы, методы самоанализа объекта...)
* Строгий режим
### API по интернационализации

Спецификация ECMAScript для API по интернационализации - дополнение к языковой спецификации ECMAScript, также стандартизированной Ecma TC39. API по интернационализации обеспечивает сопоставление (строковое сравнение), форматирование чисел, дат и времени для приложений на JavaScript, позволяя выбирать язык и проектировать функциональность в зависимости от нужд. Начальный стандарт был одобрен в декабре 2012; статус реализации в браузерах ведётся в документации `Intl` object (en-US). Спецификация по интернационализации сейчас также утверждается на ежегодной основе, и браузеры постоянно улучшают её реализацию.

DOM APIs
--------

### WebIDL

Спецификация WebIDL является связующим звеном между технологиями DOM и ECMAScript.

### Ядро DOM

Объектно-ориентированная модель документа (DOM) это кросс-платформенное, **языково-независимое соглашение** по представлению объектов и взаимодействию с ними в документах HTML, XHTML и XML. Объект в **DOM-дереве** может быть адресован и обработан с помощью своих методов. Ядро Объектно-ориентированной модели документа стандартизируется W3C и определяет языково-независимые интерфейсы, абстрагирующие HTML и XML документы как объекты, и механизмы для управления этой абстракцией. Кроме прочих вещей, опряденных в DOM, можно также найти:

* Структуру документа, древовидную модель, и архитектуру событий DOM в ядре DOM: `Node`, `Element`, `DocumentFragment`, `Document`, `DOMImplementation`, `Event`, `EventTarget`, …
* Менее строгое определение архитектуры событий DOM, также как и определённые события DOM.
* Другие вещи, такие как DOM Traversal и DOM Range.

С точки зрения ECMAScript, объекты определённые в спецификации DOM называются объектами среды исполнения ("host objects").

### HTML DOM

HTML, это язык разметки Web, который определён в терминах DOM/ is specified in terms of the DOM. Layered above the abstract concepts defined in DOM Core, HTML also defines the *meaning* of elements. The HTML DOM includes such things as the `className` property on HTML elements, or APIs such as `document.body`.

The HTML specification also defines restrictions on documents; for example, it requires all children of a `ul` element, which represents an unordered list, to be `li` elements, as those represent list items. In general, it also forbids using elements and attributes that aren't defined in a standard.

Другие API, заслуживающие внимания
----------------------------------

* Функции setTimeout и setInterval впервые были определены в интерфейсе Window в стандарте HTML.
* XMLHttpRequest позволяет отправлять асинхронные HTTP запросы.
* Объектная модель CSS абстрагировать CSS-правила как объекты
* WebWorkers обеспечивает выполнение параллельных вычислений.
* WebSockets обеспечивает низкоуровневое двунаправленное соединение.
* Canvas 2D Context это API для рисования с помощью элемента `<canvas>`..


Управление памятью - JavaScript

Управление памятью
==================

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

Низкоуровневые языки программирования (например, C) имеют низкоуровневые примитивы для управления памятью, такие как `malloc()` и `free()`. В JavaScript же память выделяется динамически при создании сущностей (т.е., объектов, строк и т.п.) и "автоматически" освобождается, когда они больше не используются. Последний процесс называется *сборкой мусора* . Слово "автоматически" является источником путаницы и зачастую создаёт у программистов на JavaScript (и других высокоуровневых языках) ложное ощущение, что они могут не заботиться об управлении памятью.

Жизненный цикл памяти
---------------------

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

1. Выделение необходимой памяти.
2. Её использование (чтение, запись).
3. Освобождение выделенной памяти, когда в ней более нет необходимости.

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

### Выделение памяти в JavaScript

#### Выделение памяти при инициализации значений переменных

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

```js
var n = 123; // выделяет память для типа number
var s = "azerty"; // выделяет память для типа string

var o = {
  a: 1,
  b: null,
}; // выделяет память для типа object и всех его внутренних переменных

var a = [1, null, "abra"]; // (like object) выделяет память для array и его внутренних значений

function f(a) {
  return a + 2;
} // выделяет память для function (которая представляет собой вызываемый объект)

// функциональные выражения также выделяют память под object
someElement.addEventListener(
  "click",
  function () {
    someElement.style.backgroundColor = "blue";
  },
  false,
);
```

#### Выделение памяти при вызовах функций

Вызовы некоторых функций также ведут к выделению памяти под объект:

```js
var d = new Date();
var e = document.createElement("div"); // выделяет память под DOM-элемент
```

Некоторые методы выделяют память для новых значений или объектов:

```js
var s = "azerty";
var s2 = s.substr(0, 3); // s2 это новый объект типа string
// Т.к. строки - это постоянные значения, интерпретатор может решить, что память выделять не нужно, но нужно лишь сохранить диапазон [0, 3].

var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // новый массив с 4 элементами в результате конкатенации элементов 'a' и 'a2'
```

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

"Использование значений", как правило, означает - чтение и запись значений из/в выделенной для них области памяти. Это происходит при чтении или записи значения какой-либо переменной, или свойства объекта или даже при передаче аргумента функции.

### Освобождение памяти, когда она более не нужна

Именно на этом этапе появляется большинство проблем из области "управления памятью". Наиболее сложной задачей в данном случае является чёткое определение того момента, когда "выделенная память более не нужна". Зачастую программист сам должен определить, что в данном месте программы данная часть памяти более уже не нужна и освободить её.

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

Сборка мусора
-------------

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

### Ссылки

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

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

### Сборка мусора на основе подсчёта ссылок

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

#### Пример

```js
var o = {
  a: {
    b: 2,
  },
}; // создано 2 объекта. Один ссылается на другой как на одно из своих полей.
// Второй имеет виртуальную ссылку, поскольку присвоен в качестве значения переменной 'o'.
// Очевидно, что ни один из них не подлежит сборке мусора.

var o2 = o; // переменная 'o2' - вторая ссылка на объект
o = 1; // теперь объект, имевший изначально ссылку на себя из 'o' имеет уникальную ссылку через переменную 'o2'

var oa = o2.a; // ссылка на поле 'a' объекта.
// Теперь на объект 2 ссылки: одна на его поле и вторая - переменная 'oa'

o2 = "yo"; // Объект, на который изначально ссылалась переменная 'o', теперь имеет ноль ссылок на неё.
// Может быть уничтожен при сборке мусора.
// Однако, на его поле 'a' всё ещё ссылается переменная 'oa', так что удалять его ещё нельзя

oa = null; // оригинальное значение поля объекта 'a' в переменной o имеет ноль ссылок на себя.
// можно уничтожить при сборке мусора.
```

#### Ограничение : циклические ссылки

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

```js
function f() {
  var o = {};
  var o2 = {};
  o.a = o2; // o ссылается на o2
  o2.a = o; // o2 ссылается на o

  return "azerty";
}

f();
```

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

#### Пример из реальной жизни

Браузеры Internet Explorer версий 6, 7 имеют сборщик мусора для DOM-объектов, работающий по принципу подсчёта ссылок. Поэтому данные браузеры можно легко принудить к порождению систематических утечек памяти (memory leaks) следующим образом:

```js
var div;
window.onload = function () {
  div = document.getElementById("myDivElement");
  div.circularReference = div; // DOM-элемент "myDivElement" получает ссылку на себя
  div.lotsOfData = new Array(10000).join("\*");
};
```

DOM-элемент "myDivElement" имеет циклическую ссылку на самого себя в поле "circularReference". Если это свойство не будет явно удалено или установлено в null, сборщик мусора всегда будет определять хотя бы одну ссылку на DOM-элемент, и будет держать DOM-элемент в памяти, даже если DOM-элемент удалят из DOM-дерева. Таким образом, если DOM-элемент содержит много данных (иллюстрируется полем "lotsOfData"), то память, используемая под эти данные, никогда не будет освобождена.

### Алгоритм "Mark-and-sweep"

Данный алгоритм сужает понятие "объект более не нужен" до "объект недоступен".

Основывается на понятии о наборе объектов, называемых *roots* (в JavaScript root'ом является глобальный объект). Сборщик мусора периодически запускается из этих roots, сначала находя все объекты, на которые есть ссылки из roots, затем все объекты, на которые есть ссылки из найденных и так далее. Стартуя из roots, сборщик мусора, таким образом, находит все *доступные* объекты и уничтожает недоступные.

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

Начиная с 2012 года, все современные веб-браузеры оснащаются сборщиками мусора, работающими исключительно по принципу mark-and-sweep ("пометь и выброси"). Все усовершенствования в области сборки мусора в интерпретаторах JavaScript (генеалогическая/инкрементальная/конкурентная/параллельная сборка мусора) за последние несколько лет представляют собой усовершенствования данного алгоритма, но не новые алгоритмы сборки мусора, поскольку дальнейшее сужение понятия "объект более не нужен" не представляется возможным.

#### Теперь циклические ссылки - не проблема

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

То же самое касается и второго примера. Как только div и его обработчик станут недоступны из roots, они оба будут уничтожены сборщиком мусора, несмотря на наличие циклических ссылок друг на друга.

#### Ограничение: некоторые объекты нуждаются в явном признаке недоступности

Хотя этот частный случай и расценивается, как ограничение, но на практике он встречается крайне редко, поэтому, в большинстве случаев, вам не нужно беспокоиться о сборке мусора.

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

* статья IBM "Шаблоны утечек памяти в JavaScript" (2007)
* статья Kangax о том, как правильно регистрировать обработчики событий для предотвращения утечек памяти (2010)
* Performance


Типы и структуры данных JavaScript - JavaScript

Типы и структуры данных JavaScript
==================================

Все языки программирования содержат встроенные типы данных, но они часто отличаются друг от друга в разных языках. Эта статья — попытка описать встроенные структуры (типы) данных, доступные в JavaScript, и их свойства. На их основе строятся другие структуры данных. Когда это возможно, то мы будем сравнивать типы данных в разных языках.

Динамическая типизация
----------------------

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

```js
var foo = 42; // сейчас foo типа Number
foo = "bar"; // а теперь foo типа String
foo = true; // foo становится типа Boolean
```

Типы данных
-----------

Стандарт ECMAScript определяет 8 типов:

* 6 типов данных являющихся примитивами:
    + Undefined (Неопределённый тип) : `typeof instance === "undefined"`
    + Boolean (Булев, Логический тип) : `typeof instance === "boolean"`
    + Number (Число) : `typeof instance === "number"`
    + String (Строка) : `typeof instance === "string"`
    + BigInt : `typeof instance === "bigint"`
    + Symbol (en-US) (в ECMAScript 6) : `typeof instance === "symbol"`
* Null (Null тип ) : `typeof instance === "object"`. Специальный примитив, используемый не только для данных но и в качестве указателя на финальную точку в Цепочке Прототипов;
* Object (Объект) : `typeof instance === "object"`. Простая структура, используемая не только для хранения данных, но и для создания других структур, где любая структура создаётся с использованием ключевого слова `new`: new Object, new Array, new Map (en-US), new Set, new WeakMap, new WeakSet, new Date и множество других структур;

И здесь нам необходимо сделать предостережение относительно использования оператора `typeof` для определения типа структур, т.к. все структуры будут возвращать `"object"` при его использовании, так как назначение `typeof` — проверка типа данных, но не структур. Если проверить тип структуры всё же необходимо, то в этом случае желательно использовать оператор instanceof, так как именно он отвечает на вопрос о том, какой конструктор был использован для создания структуры.

Стоит отметить два особых случая работы оператора `typeof`: возврат `"object"` для значения `null` и `"function"` для функций: первое принято считать ошибкой языка, сохраненной ради обратной совместимости, второе является условностью, удобной для проверки на принадлежность значения категории функций, где функция - это особый, "вызываемый", объект.

Примитивные значения
--------------------

Все типы данных в JavaScript, кроме объектов, являются иммутабельными (значения не могут быть модифицированы, а только перезаписаны новым полным значением). Например, в отличии от C, где строку можно посимвольно корректировать, в JavaScript строки пересоздаются только полностью. Значения таких типов называются «примитивными значениями».

### Булевый тип данных

Булевый тип представляет логическую сущность и имеет два значения: `true (истина)` и `false (ложь)`. Смотрите Boolean и `Boolean` для получения подробностей.

### Null

Этот тип данных имеет всего одно значение: `null`. Смотрите `null` и Null для получения подробностей.

### Undefined

Переменная, которой не было присвоено значение, будет иметь значение `undefined`. Смотрите `undefined` и undefined для получения подробностей.

### Числа

В соответствии со стандартом ECMAScript, существует только один числовой тип, который представляет собой 64-битное число двойной точности согласно стандарту IEEE 754. Другими словами, **специального типа для целых чисел в JavaScript нет**. Это означает, что при числовых операциях вы можете получить неточное (округлённое) значение. В дополнение к возможности представлять числа с плавающей запятой, есть несколько символических значений: `+Infinity` (положительная бесконечность), `-Infinity` (отрицательная бесконечность), и `NaN` (не число).

Для получения самого большого или самого меньшего доступного значения в пределах `+/-Infinity`, можно использовать константы `Number.MAX_VALUE` или `Number.MIN_VALUE`. А начиная с ECMAScript 2015, вы также можете проверить, находится ли число в безопасном для целых чисел диапазоне, используя метод `Number.isSafeInteger()`, либо константы `Number.MAX_SAFE_INTEGER` и `Number.MIN_SAFE_INTEGER`. За пределами этого диапазона операции с целыми числами будут небезопасными, и возвращать приближённые значения.

Ноль в JavaScript имеет два представления: -0 и +0. («0» это синоним +0). На практике это имеет малозаметный эффект. Например, выражение `+0 === -0` является истинным. Однако, это может проявиться при делении на ноль:

```js
> 42 / +0
Infinity
> 42 / -0
-Infinity
```

Хотя число в большинстве случаев представляет только своё значение, JavaScript предоставляет несколько бинарных операций. Они могут использоваться для того, чтобы представлять число как несколько булевых значений, с помощью битовой маски. Это считается плохой практикой, так как JavaScript предлагает другие способы представления булевых значений (например, массив элементов с булевыми значениями или объект, содержащий набор булевых свойств). Кроме того, битовые маски часто делают код более трудным для чтения, понимания и дальнейшей поддержки. Эта техника может быть необходима в условиях технических ограничений, таких как объём локального хранилища данных, или в такой экстремальной ситуации, когда каждый бит передаваемый по сети на счету. Данный подход следует использовать как крайнюю меру, когда не остаётся других путей для необходимой оптимизации.

### Текстовые строки

В JavaScript для представления текстовых данных служит тип `String`. Он представляет собой цепочку «элементов» 16-битных беззнаковых целочисленных значений. Каждый такой элемент занимает свою позицию в строке. Первый элемент имеет индекс 0, следующий — 1, и так далее. Длина строки — это количество элементов в ней.

В отличие от языков подобных C, строки в JavaScript являются иммутабельными. Это означает, что после того, как строковое значение создано, его нельзя модифицировать. Остаётся лишь создать новую строку путём совершения некой операции над исходной строкой. Например:

* Получить часть исходной строки выборкой отдельных символов, либо применением метода `String.substr()`.
* Объединить две строки в одну, применив оператор (`+`) или метод `String.concat()`.

#### Избегайте повсеместного использования строк в своём коде!

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

* Легко соединять данные в кучу сложением строк.
* Легко отлаживать (данные выглядят «как есть», в читаемом текстовом виде).
* Строки — это распространённый формат данных, используемый разнообразными API (поля ввода (en-US), значения локального хранилища, `XMLHttpRequest` возвращает ответ в виде строки, и т. д.) и использовать только строки может показаться заманчивым.

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

Используйте строки только для текстовых данных. Для составных структур преобразуйте строки в подобающие конструкции.

### Тип данных Символ (Symbol)

Символы являются нововведением JavaScript начиная с ECMAScript 2015. Символ — это **уникальное** и **иммутабельное** примитивное значение, которое может быть использовано как ключ для свойства объекта (смотрите ниже). В некоторых языках программирования символы называются атомами. Их также можно сравнить с именованными значениями перечисления (enum) в языке C. Подробнее смотрите Symbol (en-US) и `Symbol`.

### Тип данных Большое целое (BigInt)

`BigInt` является встроенным объектом, который предоставляет способ представления целых чисел, которые больше 2 53, что является наибольшим числом, которое JavaScript может надёжно представить с помощью `Number` примитива.

```js
> let bigInt = 19241924124n;
> console.log(bigInt);
19241924124n
> console.log(typeof bigInt);
"bigint"
```

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

В компьютерной терминологии, объект — это значение в памяти, на которое возможно сослаться с помощью идентификатора.

### Свойства

В JavaScript объект может расцениваться как набор свойств. Литеральная инициализация объекта задаёт определённое количество начальных свойств, и в процессе работы приложения поля могут добавляться и удаляться. Значения свойств могут иметь любой тип, включая другие объекты, что позволяет строить сложные, разветвлённые иерархии данных. Каждое свойство объекта идентифицируется ключом, в качестве которого может выступать значение с типом Строка или Символ.

Есть два типа свойств: свойство-значение и свойство-акцессор (свойство, обёрнутое в геттер и сеттер). Они отличаются определёнными атрибутами.

#### Свойство-значение

Ассоциирует ключ со значением, и имеет следующие атрибуты:

| Атрибут | Тип | Описание | Значение по умолчанию |
| --- | --- | --- | --- |
| [[Value]] | Любой тип JavaScript | Значение, возвращаемое при обращении к свойству. | undefined |
| [[Writable]] | Boolean | Если `false`, то [[Value]] свойства не может быть изменено. | false |
| [[Enumerable]] | Boolean | Если `true`, свойство будет перечислено в цикле for...in. Смотрите подробнее Перечисляемость и владение свойствами. | false |
| [[Configurable]] | Boolean | Если `false`, то свойство не может быть удалено, а его атрибуты, кроме [[Value]] и [[Writable]] не могут быть изменены. | false |

| Атрибут | Тип | Описание |
| --- | --- | --- |
| Read-only | Boolean | Зарезервировано по атрибуту [[Writable]] ES5. |
| DontEnum | Boolean | Зарезервировано по атрибуту [[Enumerable]] ES5. |
| DontDelete | Boolean | Зарезервировано по атрибуту [[Configurable]] ES5. |

#### Свойство-акцессор

Ассоциирует ключ с одной из двух функций-акцессоров (геттер и сеттер) для получения или изменения значения свойства, и имеет следующий атрибуты:

| Атрибут | Тип | Описание | Значение по умолчанию |
| --- | --- | --- | --- |
| [[Get]] | Function или undefined | Функция вызывается без параметров и возвращает значение свойства каждый раз, когда происходит чтение свойства. Смотрите также `get` (en-US). | undefined |
| [[Set]] | Function или undefined | Функция вызывается с одним аргументом, содержащим присваиваемое значение, каждый раз, когда происходит попытка присвоить свойству новое значение. Смотрите также `set` (en-US). | undefined |
| [[Enumerable]] | Boolean | Если `true`, свойство будет перечислено в цикле for...in. | false |
| [[Configurable]] | Boolean | Если `false`, то свойство не может быть удалено, и не может быть преобразовано в свойство-значение. | false |

**Примечание:** Атрибуты обычно используются движком JavaScript, поэтому вы не можете обратиться к ним напрямую (смотрите подробнее Object.defineProperty()). Вот почему в таблицах выше они помещены в двойные квадратные скобки вместо одиночных.

### «Обычные» объекты и функции

Объект JavaScript — это таблица соотношений между ключами и значениями. Ключи — это строки (или `Symbol`), а значения могут быть любыми. Это делает объекты полностью отвечающими определению хеш-таблицы.

Функции — это обычные объекты, имеющие дополнительную возможность быть вызванными для исполнения.

### Даты

Для работы с датами служит встроенный глобальный объект `Date`.

### Массивы общие и типизированные

Массив — это обычный объект с дополнительной связью между целочисленными ключами его свойств и специальным свойством length. Вдобавок ко всему, массивы наследуют `Array.prototype`, предоставляющий исчерпывающий набор методов для манипуляции массивами. Например, метод `indexOf` (служит для поиска значения в массиве), `push` (en-US) (добавляет элемент в конец массива) и т. д. Всё это делает массив идеальным кандидатом для представления списков и перечислений.

Типизированные массивы являются подобными массивам представлениями наборов бинарных данных и предлагают множество методов, семантика которых аналогична аналогам массива. "Типизированный массив" это общий термин для ряда структур данных, включая `Int8Array`, `Float32Array` и т.д. Подробнее о них можно узнать в руководстве о типизированных массивах. Типизированные массивы часто используются вместе с `ArrayBuffer` и `DataView`.

### Коллекции: Maps, Sets, WeakMaps, WeakSets

Эти наборы данных используют ссылку на объект в качестве ключа, и введены в JavaScript с приходом ECMAScript Edition 6. `Set` и `WeakSet` являют собой набор уникальных объектов, в то время как `Map` (en-US) и `WeakMap` ассоциируют с объектом (выступающим в качестве ключа) некоторое значение. Разница между Map и WeakMap заключается в том, что только у Map ключи являются перечисляемыми. Это позволяет оптимизировать сборку мусора для WeakMap.

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

Обычно, для привязки некоторых данных к узлу DOM, приходится устанавливать свойства этому узлу непосредственно, либо использовать его атрибуты `data-*`. Обратной стороной такого подхода является то, что эти данные будут доступны любому скрипту, работающему в том же контексте. Maps и WeakMaps дают возможность приватной привязки данных к объекту.

### Структурированные данные: JSON

JSON (JavaScript Object Notation) — это легковесный формат обмена данными, происходящий от JavaScript, но используемый во множестве языков программирования. JSON строит универсальные структуры данных. Смотрите JSON и `JSON` для детального изучения.

### Больше объектов и стандартная библиотека

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

Определение типов оператором `typeof`
-------------------------------------

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

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

* Nicholas Zakas, коллекция некоторых классических структур данных и алгоритмов, написанных на JavaScript.
* Реализация некоторых структур данных для JavaScript


Справочник по JavaScript - JavaScript

Справочник по JavaScript
========================

Этот раздел MDN служит хранилищем фактов о языке JavaScript. Весь язык подробно описан здесь. При написании кода JavaScript вы будете часто ссылаться на эти страницы (отсюда и название "Справочник по JavaScript").

Язык JavaScript предназначен для использования в какой-либо более крупной среде, будь то браузер, серверные скрипты или что-то подобное. По большей части, этот справочник пытается быть независимым от среды и не ориентирован на среду веб-браузера.

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

Встроенные модули
-----------------

Эта глава описывает все стандартные встроенные объекты JavaScript вместе с их методами и свойствами.

### Значения свойств

* `globalThis`
* `Infinity`
* `NaN`
* `undefined`
### Свойства функции

* `eval()`
* `isFinite()`
* `isNaN()`
* `parseFloat()`
* `parseInt()`
* `decodeURI()`
* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`
* `escape()`
Устарело
* `unescape()`
Устарело
### Фундаментальные объекты

* `Object`
* `Function`
* `Boolean`
* `Symbol`
### Объекты ошибок

* `Error`
* `AggregateError` (en-US)
* `EvalError`
* `RangeError`
* `ReferenceError`
* `SyntaxError`
* `TypeError`
* `URIError`
* `InternalError`
Non-standard
### Числа и даты

* `Number`
* `BigInt`
* `Math`
* `Date`
### Обработка текста

* `String`
* `RegExp`
### Индексированные коллекции

* `Array`
* `Int8Array`
* `Uint8Array` (en-US)
* `Uint8ClampedArray`
* `Int16Array` (en-US)
* `Uint16Array` (en-US)
* `Int32Array`
* `Uint32Array` (en-US)
* `BigInt64Array` (en-US)
* `BigUint64Array` (en-US)
* `Float32Array`
* `Float64Array`
### Коллекции с ключами

* `Map` (en-US)
* `Set`
* `WeakMap`
* `WeakSet`
### Структурированные данных

* `ArrayBuffer`
* `SharedArrayBuffer`
* `DataView`
* `Atomics`
* `JSON`
### Управление памятью

* `WeakRef` (en-US)
* `FinalizationRegistry` (en-US)
### Абстракционные объекты управления

* `Promise`
* `GeneratorFunction`
* `AsyncGeneratorFunction` (en-US)
* `Generator`
* `AsyncGenerator` (en-US)
* `AsyncFunction`
### Объекты отражения

* `Reflect`
* `Proxy`
### Интернационализация

* `Intl`
* `Intl.Collator`
* `Intl.DateTimeFormat`
* `Intl.DisplayNames` (en-US)
* `Intl.ListFormat`
* `Intl.Locale` (en-US)
* `Intl.NumberFormat`
* `Intl.PluralRules` (en-US)
* `Intl.RelativeTimeFormat` (en-US)
* `Intl.Segmenter` (en-US)
Инструкции
----------

Эта глава описывает все инструкции и объявления JavaScript.

### Управление потоком

* `return`
* `break`
* `continue`
* `throw`
* `if...else`
* `switch`
* `try...catch`
### Объявление переменных

* `var`
* `let`
* `const`
### Функции и классы

* `function`
* `function*`
* `async function`
* `async function*` (en-US)
* `class`
### Итерации

* `do...while`
* `for`
* `for...in`
* `for...of`
* `for await...of`
* `while`
### Другое

* Empty
* Block
* Expression statement (en-US)
* `debugger`
* `export`
* `import`
* label
* `with`
Устарело
Выражения и операторы
---------------------

JavaScript expressions and operators.

### Основные выражения

* `this`
* Литералы
* `[]`
* `{}`
* `function`
* `class`
* `function*`
* `async function`
* `async function*` (en-US)
* `/abc/i`
* ``string``
* `( )`
### Второстепенные выражения

* Property accessors
* `?.`
* `new`
* `new.target`
* `import.meta`
* `super`
* `import()` (en-US)
### Инкремент и дикремент

* `A++` (en-US)
* `A--`
* `++A` (en-US)
* `--A`
### Унарные оператоты

* `delete`
* `void`
* `typeof`
* `+` (en-US)
* `-` (en-US)
* `~` (en-US)
* `!`
* `await`
### Арифмитические оператоты

* `**` (en-US)
* `*` (en-US)
* `/` (en-US)
* `%` (en-US)
* `+`
* `-` (en-US)
### Реляционные операторы

* `<` (en-US) (Меньше чем)
* `>` (en-US) (Больше чем)
* `<=` (en-US)
* `>=` (en-US)
* `instanceof`
* `in`
### Оператоы сравнения

* `==` (en-US)
* `!=` (en-US)
* `===` (en-US)
* `!==` (en-US)
### Операторы побитового сдвига

* `<<` (en-US)
* `>>` (en-US)
* `>>>` (en-US)
### Двоичные побитовые операторы

* `&`
* `|` (en-US)
* `^` (en-US)
### Двоичные логические операторы

* `&&`
* `||`
* `??`
### Условный (тернарный) оператор

* `(condition ? ifTrue : ifFalse)`
### Операторы присваивания

* `=`
* `*=` (en-US)
* `/=` (en-US)
* `%=` (en-US)
* `+=`
* `-=` (en-US)
* `<<=` (en-US)
* `>>=` (en-US)
* `>>>=` (en-US)
* `&=` (en-US)
* `^=` (en-US)
* `|=` (en-US)
* `**=` (en-US)
* `&&=`
* `||=`
* `??=`
* `[a, b] = arr`, `{ a, b } = obj`
### Операторы доходности

* `yield`
* `yield*`
### Spread синтаксис

* `...obj`
### Оператор запятой

* `,`
Функции
-------

JavaScript функции.

* Стрелочные функции
* Стандартные параметры
* Остальные параметры
* `arguments`
* Определения методов
* getter
* setter
Классы
------

JavaScript классы.

* `constructor`
* `extends`
* Особенности приватных классов
* Поля открытого класса
* `static`
* Статические блоки инициализации (en-US)
Дополнительные справочные страницы
----------------------------------

* Lexical grammar
* Типы и структуры данных
* Протоколы итерации
* Конечные запятые
* Ошибки
* Strict mode
* Deprecated features


Наследование и цепочка прототипов - JavaScript

Наследование и цепочка прототипов
=================================

Модель наследования в JavaScript может озадачить опытных разработчиков на высокоуровневых объектно-ориентированных языках (таких, например, как Java или C++), поскольку она динамическая и не включает в себя реализацию понятия `class` (хотя ключевое слово `class`, бывшее долгие годы зарезервированным, и приобрело практическое значение в стандарте ES2015, однако, классы в JavaScript представляют собой лишь "синтаксический сахар" поверх прототипно-ориентированной модели наследования).

В плане наследования JavaScript работает лишь с одной сущностью: объектами. Каждый объект имеет внутреннюю ссылку на другой объект, называемый его **прототипом**. У объекта-прототипа также есть свой собственный прототип и так далее до тех пор, пока цепочка не завершится объектом, у которого свойство prototype равно `null`. По определению, `null` не имеет прототипа и является завершающим звеном в **цепочке прототипов**.

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

Наследование с цепочкой прототипов
----------------------------------

### Наследование свойств

 Объекты в JavaScript — динамические "контейнеры", наполненные свойствами (называемыми **собственными свойствами**). Каждый объект содержит ссылку на свой объект-прототип.
 При попытке получить доступ к какому-либо свойству объекта, свойство вначале ищется в самом объекте, затем в прототипе объекта, после чего в прототипе прототипа, и так далее. Поиск ведётся до тех пор, пока не найдено свойство с совпадающим именем или не достигнут конец цепочки прототипов.

```js
// В этом примере someObject.[[Prototype]] означает прототип someObject.
// Это упрощённая нотация (описанная в стандарте ECMAScript).
// Она не может быть использована в реальных скриптах.

// Допустим, у нас есть объект 'o' с собственными свойствами a и b
// {a:1, b:2}

// o.[[Prototype]] имеет свойства b и с
// {b:3, c:4}

// Далее, o.[[Prototype]].[[Prototype]] является null
// null - это окончание в цепочке прототипов
// по определению, null не имеет свойства [[Prototype]]

// В итоге полная цепочка прототипов выглядит так:
// {a:1, b:2} ---> {b:3, c:4} ---> null

console.log(o.a); // 1
// Есть ли у объекта 'o' собственное свойство 'a'?
// Да, и его значение равно 1

console.log(o.b); // 2
// Есть ли у объекта 'o' собственное свойство 'b'?
// Да, и его значение равно 2.
// У прототипа o.[[Prototype]] также есть свойство 'b',
// но обращения к нему в данном случае не происходит.
// Это и называется "property shadowing" (затенение свойства)

console.log(o.c); // 4
// Есть ли у объекта 'o' собственное свойство 'с'?
// Нет, тогда поищем его в прототипе.
// Есть ли у объекта o.[[Prototype]] собственное свойство 'с'?
// Да, оно равно 4

console.log(o.d); // undefined
// Есть ли у объекта 'o' собственное свойство 'd'?
// Нет, тогда поищем его в прототипе.
// Есть ли у объекта o.[[Prototype]] собственное свойство 'd'?
// Нет, продолжаем поиск по цепочке прототипов.
// o.[[Prototype]].[[Prototype]] равно null, прекращаем поиск,
// свойство не найдено, возвращаем undefined
```

При добавлении к объекту нового свойства, создаётся новое собственное свойство. Единственным исключением из этого правила являются наследуемые свойства, имеющие getter или setter.

### Наследование "методов"

JavaScript не имеет "методов" в смысле, принятом в классической модели ООП. В JavaScript любая функция может быть добавлена к объекту в виде его свойства. Унаследованная функция ведёт себя точно так же, как любое другое свойство объекта, в том числе и в плане "затенения свойств" (property shadowing), как показано в примере выше (в данном конкретном случае это форма *переопределения метода - method overriding*).

При выполнении унаследованной функции значение `this`(/ru/docs/Web/JavaScript/Reference/Operators/this) указывает на объект-потомок, а не на прототип, в котором функция является собственным свойством.

```js
var o = {
  a: 2,
  m: function () {
    return this.a + 1;
  },
};

console.log(o.m()); // 3
// в этом случае при вызове 'o.m' this указывает на 'o'

var p = Object.create(o);
// 'p' - потомок 'o'

p.a = 12; // создаст собственное свойство 'a' объекта 'p'
console.log(p.m()); // 13
// при вызове 'p.m' this указывает на 'p'.
// т.е. когда 'p' наследует функцию 'm' объекта 'o',
// this.a означает 'p.a', собственное свойство 'a' объекта 'p'
```

Различные способы создания объектов и получаемые в итоге цепочки прототипов
---------------------------------------------------------------------------

### Создание объектов с помощью литералов

```js
var o = { a: 1 };

// Созданный объект 'o' имеет Object.prototype в качестве своего [[Prototype]]
// у 'o' нет собственного свойства 'hasOwnProperty'
// hasOwnProperty — это собственное свойство Object.prototype.
// Таким образом 'o' наследует hasOwnProperty от Object.prototype
// Object.prototype в качестве прототипа имеет null.
// o ---> Object.prototype ---> null

var a = ["yo", "whadup", "?"];

// Массивы наследуются от Array.prototype
// (у которого есть такие методы, как indexOf, forEach и т.п.).
// Цепочка прототипов при этом выглядит так:
// a ---> Array.prototype ---> Object.prototype ---> null

function f() {
  return 2;
}

// Функции наследуются от Function.prototype
// (у которого есть такие методы, как call, bind и т.п.):
// f ---> Function.prototype ---> Object.prototype ---> null
```

### Создание объектов с помощью конструктора

В JavaScript "конструктор" — это "просто" функция, вызываемая с оператором new.

```js
function Graph() {
  this.vertexes = [];
  this.edges = [];
}

Graph.prototype = {
  addVertex: function (v) {
    this.vertexes.push(v);
  },
};

var g = new Graph();
// объект 'g' имеет собственные свойства 'vertexes' и 'edges'.
// g.[[Prototype]] принимает значение Graph.prototype при выполнении new Graph().
```

### Object.create

В ECMAScript 5 представлен новый метод создания объектов: Object.create. Прототип создаваемого объекта указывается в первом аргументе этого метода:

```js
var a = { a: 1 };
// a ---> Object.prototype ---> null

var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1 (унаследовано)

var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null

var d = Object.create(null);
// d ---> null
console.log(d.hasOwnProperty);
// undefined, т.к. 'd' не наследуется от Object.prototype
```

### Используя ключевое слово `class`

С выходом ECMAScript 6 появился целый набор ключевых слов, реализующих классы. Они могут показаться знакомыми людям, изучавшим языки, основанные на классах, но есть существенные отличия. JavaScript был и остаётся прототипно-ориентированным языком. Новые ключевые слова: "`class`", "`constructor`", "`static`", "`extends`" и "`super`".

```js
"use strict";

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height \* this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }
}

var square = new Square(2);
```

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

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

Кроме того, при циклическом переборе свойств объекта будет обработано каждое свойство, присутствующее в цепочке прототипов.

Если вам необходимо проверить, определено ли свойство у *самого объекта*, а не где-то в его цепочке прототипов, вы можете использовать метод `hasOwnProperty`, который все объекты наследуют от `Object.prototype`.

`hasOwnProperty` — единственная существующая в JavaScript возможность работать со свойствами, не затрагивая цепочку прототипов.

**Примечание:** Примечание: Для проверки существования свойства недостаточно проверять, эквивалентно ли оно `undefined`. Свойство может вполне себе существовать, но при этом ему может быть присвоено значение `undefined`.

### Плохая практика: расширение базовых прототипов

Одной из частых ошибок является расширение `Object.prototype` или других базовых прототипов.

Такой подход называется monkey patching и нарушает принцип *инкапсуляции*. Несмотря на то, что ранее он использовался в таких широко распространённых фреймворках, как например, Prototype.js, в настоящее время не существует разумных причин для его использования, поскольку в данном случае встроенные типы "захламляются" дополнительной нестандартной функциональностью.

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

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

`B` наследует от `A`:

```js
function A(a) {
  this.varA = a;
}

// What is the purpose of including varA in the prototype when A.prototype.varA will always be shadowed by
// this.varA, given the definition of function A above?
A.prototype = {
  varA: null, // Shouldn't we strike varA from the prototype as doing nothing?
  // perhaps intended as an optimization to allocate space in hidden classes?
  // https://developers.google.com/speed/articles/optimizing-javascript#Initializing instance variables
  // would be valid if varA wasn't being initialized uniquely for each instance
  doSomething: function () {
    // ...
  },
};

function B(a, b) {
  A.call(this, a);
  this.varB = b;
}
B.prototype = Object.create(A.prototype, {
  varB: {
    value: null,
    enumerable: true,
    configurable: true,
    writable: true,
  },
  doSomething: {
    value: function () {
      // переопределение
      A.prototype.doSomething.apply(this, arguments); // call super
      // ...
    },
    enumerable: true,
    configurable: true,
    writable: true,
  },
});
B.prototype.constructor = B;

var b = new B();
b.doSomething();
```

Важно:

* Типы определяются в `.prototype`
* Для наследования используется `Object.create()`
prototype и Object.getPrototypeOf
---------------------------------

Как уже упоминалось, JavaScript может запутать разработчиков на Java или C++, ведь в нём совершенно нет "нормальных" классов. Всё, что мы имеем - лишь объекты. Даже те "classes", которые мы имитировали в статье, тоже являются функциональными объектами.

Вы наверняка заметили, что у `function A` есть особое свойство `prototype`. Это свойство работает с оператором `new`. Ссылка на объект-прототип копируется во внутреннее свойство `[[Prototype]]` нового объекта. Например, в этом случае `var a1 = new A()`, JavaScript (после создания объекта в памяти и до выполнения функции function `A()`) устанавливает `a1.[[Prototype]] = A.prototype`. Потом, при попытке доступа к свойству нового экземпляра объекта, JavaScript проверяет, принадлежит ли свойство непосредственно объекту. Если нет, то интерпретатор ищет в свойстве `[[Prototype]]`. Всё, что было определено в `prototype,` в равной степени доступно и всем экземплярам данного объекта. При внесении изменений в `prototype` все эти изменения сразу же становятся доступными и всем экземплярам объекта.

`[[Prototype]]` работает *рекурсивно*, то есть при вызове:

```js
var o = new Foo();
```

JavaScript на самом деле выполняет что-то подобное:

```js
var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o);
```

а когда вы делаете так:

```js
o.someProp;
```

 JavaScript проверяет, есть ли у **`o`** свойство `someProp`.
 и если нет, то проверяет `Object.getPrototypeOf(o).someProp`
 а если и там нет, то ищет в `Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp` и так далее.

Заключение
----------

 Важно чётко понимать принципы работы прототипной модели наследования, прежде чем начинать писать сложный код с её использованием.
 При написании JavaScript-кода, использующего наследование, следует помнить о длине цепочек прототипов и стараться делать их как можно более короткими во избежание проблем с производительностью во время выполнения кода.
 Расширять базовые прототипы следует исключительно для поддержания совместимости кода с отдельными "древними" реализациями JavaScript, - во всех прочих случаях это плохая практика.


Руководство JavaScript - JavaScript

Руководство JavaScript
======================

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

Главы
-----

Это руководство разделено на несколько глав:

* Введение
Об этом руководстве
О JavaScript
JavaScript и Java
ECMAScript
Инструменты
Hello World
* Грамматика и типы
Базовый синтаксис и комментарии
Объявления
Область видимости переменных
Поднятие переменных
Структуры и типы данных
Литералы
* Порядок выполнения и обработка ошибок
`if...else`
`switch`
`try`/`catch`/`throw`
Объекты `Error`
Объект `Promise`
* Циклы и итерации
`for while do...while break/continue for..in for..of`

* Функции
Объявление функций
Вызов функций
Область видимости функций
Замыкания
Аргументы и параметры
Стрелочные функции
* Выражения и операторы
Присваивание и Сравнение
Арифметические операторы
Побитовые операторы и логические операторы
Условный (тернарный) операторы
* Числа и даты Числовые литералы
Объект `Number`
Объект `Math`
Объект `Date`
* Форматирование текста
Строковые литералы
Объект `String`
Шаблонные литералы
Интернационализация
Регулярные выражения

* Индексированные коллекции
Массивы
Типизированные массивы
* Коллекции
`Map`
`WeakMap`
`Set`
`WeakSet`
* Работа с объектами
Объекты и свойства
Создание объектов
Определение методов
Геттеры и Сеттеры
* Подробнее про объектную модель (en-US)
Прототипно-ориентированное ООП (en-US)
Создание иерархии объектов (en-US)
Наследование (en-US)

* Промисы
Гарантии
Цепочка вызовов
Распространённые ошибки
Композиция
Порядок выполнения
* Итераторы и Генераторы
Итераторы
Итерируемые объекты
Генераторы
* Мета
программирование
Объект `Proxy`
Обработчики и ловушки
Отзываемый `Proxy`
Рефлексия
* Следующая статья »


Enumerability and ownership of properties - JavaScript

Enumerability and ownership of properties
=========================================

В языке JavaScript свойства объектов могут быть перечисляемыми или неперечисляемыми (встречается вариант перевода: счётные или несчётные). Если внутреннему флагу [[Enumerable]] свойства присвоить значение true, то данное свойство становится перечисляемым. Это происходит по умолчанию для свойств, созданных простым присваиванием или через инициализацию свойств (свойства, определённые через Object.defineProperty получают по умолчанию значение флага [[Enumerable]] равным false). Перечисляемые свойства участвуют в итерации в цикле for...in, если только имя свойства не Символ. Принадлежность свойства определяется тем, принадлежит ли оно непосредственно объекту или получено из цепочки прототипов. Также можно получить весь список свойств объекта. Ниже, в таблице, указаны возможные способы нахождения, получения и итерации свойств объектов. Некоторые из них нельзя использовать без дополнительного кода, примеры которого приведены после таблицы.

 Перечисляемость и принадлежность свойств - встроенные методы определения,
 получения и итерации
 | Назначение | Свойства объекта | Свойства объекта и его прототипов | Свойства из цепочки прототипов |
| --- | --- | --- | --- |
| Определение |

| Перечисляемые | Неперечисляемые | Перечисляемые и Неперечисляемые |
| --- | --- | --- |
| `propertyIsEnumerable (en-US)` | `hasOwnProperty`
 и !`propertyIsEnumerable (en-US)` | `hasOwnProperty` |

 | Недоступно без дополнительного кода | Недоступно без дополнительного кода |
| Получение |

| Перечисляемые | Неперечисляемые | Перечисляемые и Неперечисляемые |
| --- | --- | --- |
| `Object.keys (en-US)` |
 Получить
 `getOwnPropertyNames (en-US)`, выбрать свойства, не удовлетворяющие
 `propertyIsEnumerable (en-US)` | `getOwnPropertyNames (en-US)` |

 | Недоступно без дополнительного кода | Недоступно без дополнительного кода |
| Итерация |

| Перечисляемые | Неперечисляемые | Перечисляемые и Неперечисляемые |
| --- | --- | --- |
|
 Итерация по массиву
 `Object.keys (en-US)` |
 Итерация по
 `getOwnPropertyNames (en-US)`, с выбранными свойствами, не удовлетворяющими
 `propertyIsEnumerable (en-US)` |
 Итерация по
 `getOwnPropertyNames (en-US)` |

 |

| Перечисляемые | Неперечисляемые | Перечисляемые и Неперечисляемые |
| --- | --- | --- |
| `for..in (en-US)` | Недоступно без дополнительного кода | Недоступно без дополнительного кода |

 | Недоступно без дополнительного кода |

Доступ к свойствам по их перечисляемости/принадлежности
-------------------------------------------------------

Хотим заметить, что данный алгоритм эффективен не для всех классов.

* Определение свойства: `SimplePropertyRetriever.theGetMethodYouWant(obj).indexOf(prop) > -1`
* Итерация: `SimplePropertyRetriever.theGetMethodYouWant(obj).forEach(function (value, prop) {});` (or use `filter()`, `map()`, etc.)

```js
var SimplePropertyRetriever = {
  getOwnEnumerables: function (obj) {
    return this.\_getPropertyNames(obj, true, false, this._enumerable);
    // Или можно использовать for..in, отфильтрованный по hasOwnProperty или проще: return Object.keys(obj);
  },
  getOwnNonenumerables: function (obj) {
    return this.\_getPropertyNames(obj, true, false, this._notEnumerable);
  },
  getOwnEnumerablesAndNonenumerables: function (obj) {
    return this.\_getPropertyNames(
      obj,
      true,
      false,
      this._enumerableAndNotEnumerable,
    );
    // Или можно использовать: return Object.getOwnPropertyNames(obj);
  },
  getPrototypeEnumerables: function (obj) {
    return this.\_getPropertyNames(obj, false, true, this._enumerable);
  },
  getPrototypeNonenumerables: function (obj) {
    return this.\_getPropertyNames(obj, false, true, this._notEnumerable);
  },
  getPrototypeEnumerablesAndNonenumerables: function (obj) {
    return this.\_getPropertyNames(
      obj,
      false,
      true,
      this._enumerableAndNotEnumerable,
    );
  },
  getOwnAndPrototypeEnumerables: function (obj) {
    return this.\_getPropertyNames(obj, true, true, this._enumerable);
    // Или можно использовать for..in
  },
  getOwnAndPrototypeNonenumerables: function (obj) {
    return this.\_getPropertyNames(obj, true, true, this._notEnumerable);
  },
  getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) {
    return this.\_getPropertyNames(
      obj,
      true,
      true,
      this._enumerableAndNotEnumerable,
    );
  },
  // Private static property checker callbacks
  \_enumerable: function (obj, prop) {
    return obj.propertyIsEnumerable(prop);
  },
  \_notEnumerable: function (obj, prop) {
    return !obj.propertyIsEnumerable(prop);
  },
  \_enumerableAndNotEnumerable: function (obj, prop) {
    return true;
  },
  // По мотивам http://stackoverflow.com/a/8024294/271577
  \_getPropertyNames: function getAllPropertyNames(
    obj,
 iterateSelfBool,
 iteratePrototypeBool,
 includePropCb,
  ) {
    var props = [];

    do {
      if (iterateSelfBool) {
        Object.getOwnPropertyNames(obj).forEach(function (prop) {
          if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
            props.push(prop);
          }
        });
      }
      if (!iteratePrototypeBool) {
        break;
      }
      iterateSelfBool = true;
    } while ((obj = Object.getPrototypeOf(obj)));

    return props;
  },
};
```

Определимость свойств
---------------------

|  | `in` | `for..in` | `hasOwnProperty` | `propertyIsEnumerable` | `in Object.keys` | `in Object.getOwnPropertyNames` |
| --- | --- | --- | --- | --- | --- | --- |
| Перечисляемые | true | true | true | true | true | true |
| Неперечисляемые | true | false | true | false | false | true |
| Унаследованные Перечисляемые | true | true | false | false | false | false |
| Унаследованные Неперечисляемые | true | false | false | false | false | false |

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

* `in` (en-US)
* `for..in` (en-US)
* `hasOwnProperty`
* `propertyIsEnumerable` (en-US)
* `getOwnPropertyNames` (en-US)
* `Object.keys` (en-US)