Числа и даты - JavaScript

Числа и даты
============

* « Предыдущая статья
* Следующая статья »

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

Числа
-----

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

Вы можете использовать четыре типа числовых литералов: десятичный, двоичный, восьмеричный и шестнадцатеричный.

### Десятичные числа

```js
1234567890;
42;

// Будьте внимательны при использование нулей в начале чисел:

0888; // 888 обрабатывается как десятичное
0777; // обрабатывается как восьмеричное в нестрогой форме (511 в десятичной)
```

Обратите внимание, что десятичные литералы могут начинаться с нуля (`0`) за которым следует другая десятичная цифра, но если следующая за нулём цифра меньше 8, то число обрабатывается как восьмеричное.

### Двоичные числа

Синтаксис двоичных чисел использует ведущий 0 за которым следует латинская буква "B" в верхнем или нижнем регистре (`0b` or `0B`). Если цифры после `0b` не являются 0 или 1, то будет сгенерированно `SyntaxError` с сообщением: "Missing binary digits after 0b".

```js
var FLT\_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648
var FLT\_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT\_MANTISSA = 0b00000000011111111111111111111111; // 8388607
```

### Восьмеричные числа

Синтаксис восьмеричных чисел использует ноль в начале. Если цифры после 0 не входят в диапазон от 0 до 7, число будет интерпретировано как десятичное.

```js
var n = 0755; // 493
var m = 0644; // 420
```

### Шестнадцатеричные числа

Синтаксис шестнадцатеричных чисел использует ведущий 0 за которым следует латинская буква "X" в верхнем или нижнем регистре (`0x` or `0X`). Если цифры после 0x не входят в диапазон (0123456789ABCDEF), то будет сгенерированно `SyntaxError` с сообщением: "Identifier starts immediately after numeric literal".

```js
0xfffffffffffffffff; // 295147905179352830000
0x123456789abcdef; // 81985529216486900
0xa; // 10
```

Объект Number
-------------

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

```js
var biggestNum = Number.MAX\_VALUE;
var smallestNum = Number.MIN\_VALUE;
var infiniteNum = Number.POSITIVE\_INFINITY;
var negInfiniteNum = Number.NEGATIVE\_INFINITY;
var notANum = Number.NaN;
```

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

В следующей таблице приведён список свойств объекта `Number`.

| Свойство | Описание |
| --- | --- |
| `Number.MAX_VALUE` | Наибольшее число из возможных для представления |
| `Number.MIN_VALUE` | Наименьшее число из возможных для представления |
| `Number.NaN` | Специальное "Не числовое" ("not a number") значение |
| `Number.NEGATIVE_INFINITY` | Специальное значение "Минус бесконечность"; возвращается при переполнении |
| `Number.POSITIVE_INFINITY` | Специальное значение "Плюс бесконечность"; возвращается при переполнении |
| `Number.EPSILON` | Разница между единицей и наименьшим значением, большим единицы, которое может быть представлено типом `Number`. |
| `Number.MIN_SAFE_INTEGER` | Минимальное целое, безопасное число в JavaScript. |
| `Number.MAX_SAFE_INTEGER` | Максимальное целое, безопасное число в JavaScript. |

| Метод | Описание |
| --- | --- |
| `Number.parseFloat()` | Принимает строку как аргумент, и возвращает числовое значение с плавающей точкой, которое удалось распознать. Тоже самое что и глобальная функция `parseFloat()`. |
| `Number.parseInt()` | Принимает строку как аргумент, и возвращает целочисленное значение в заданной системе исчисления, которое удалось распознать. Тоже самое что и глобальная функция `parseInt()`. |
| `Number.isFinite()` | Определяет, является ли число, переданное в качестве аргумента, конечным. |
| `Number.isInteger()` | Определяет, является ли число, переданное в качестве аргумента, целым. |
| `Number.isNaN()` | Определяет, является ли число, переданное в качестве аргумента, `NaN` (не числом). Аналогичный, но более надёжный метод чем глобальная функция `isNaN()`. |
| `Number.isSafeInteger()` | Определяет, является ли .число, переданное в качестве аргумента, целым и безопасным. |

`Прототип Number` предоставляет ряд методов, для получения значения числа в различных форматах. В следующей таблице перечислены методы, доступные через `Number.prototype`.

| Метод | Описание |
| --- | --- |
| `toExponential()` | Возвращает строку, представляющую число в экспоненциальном представлении. |
| `toFixed()` | Возвращает строку, представляющую число с заданным количеством разрядов после запятой. |
| `toPrecision()` | Возвращает строку, представляющую число с указанной точностью. |

`Объект Math`
-------------

Встроенный глобальный объект `Math` содержит свойства и методы для математических констант и функций. Например, свойство объекта `Math` `PI` содержит значение математической константы "Пи" (3.141...), которые вы можете использовать в программе как

```js
Math.PI;
```

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

```js
Math.sin(1.56);
```

Заметьте, что все тригонометрические методы объекта `Math` принимают аргументы в радианах.

В следующей таблице перечислены методы объекта `Math`.

| Метод | Описание |
| --- | --- |
| `abs()` | Возвращает абсолютное значение (модуль) аргумента |
| `sin()`, `cos()`, `tan()` | Стандартные тригонометрические функции; принимают аргументы в радианах |
| `asin()`, `acos()`, `atan()`, `atan2()` | Обратные тригонометрические функции; возвращают значения в радианах |
| `sinh()`, `cosh()`, `tanh()` | Гиперболические тригонометрические функции; принимают аргументы в гиперболических углах |
| `asinh()`, `acosh()`, `atanh()` | Обратные гиперболические тригонометрические функции; возвращают значения в гиперболических углах |
| `pow()`, `exp()`, `expm1()`, `log10()`, `log1p()`, `log2()` | Экспоненциальные и логорифмические функции |
| `floor()`, `ceil()` | Возвращают наибольшее/наименьшее целое, которое меньше/больше или равно входному значению |
| `min()`, `max()` | Возвращают наибольшее или наименьшее (соответственно) из входных числовых значений, перечисленных через запятую |
| `random()` | Возвращает случайное число от 0 до 1 |
| `round()`, `fround()`, `trunc()`, | Функции округления и отсечения дробной части |
| `sqrt()`, `cbrt()`, `hypot()` | Корень квадратный, корень кубический, корень квадратный из суммы квадратов аргументов |
| `sign()` | Знак числа, показывает является ли входное число позитивным, негативным или равным нулю |
| `clz32()`, `imul()` | Количество первых нулевых бит в 32-битном двоичном представлении. Возвращает результат Си-подобного 32-битного целочисленного умножения двух аргументов. |

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

`Объект Date`
-------------

JavaScript не имеет отдельного типа данных для хранения дат. Однако, вы можете использовать объект `Date` и его методы для работы с датами и временем в вашем приложении. Объект `Date` имеет большое количество методов для записи, чтения и оперирования датой и временем, а свойств не имеет ни одного.

JavaScript оперирует датами во многом аналогично языку Java. Для работы с датой эти два языка имеют множество одинаковых методов, и оба они хранят даты как количество миллисекунд, прошедших с 00:00:00 1 Января 1970 года.

Период значений, которые может принимать Data, простирается от -100 000 000 до100 000 000 дней, относительно 1 Января 1970 года.

Чтобы создать свой экземпляр объекта `Date используйте такой код`:

```js
var dateObjectName = new Date([parameters]);
```

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

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

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

* Пусто: создаёт текущую дату и время. Пример: `today = new Date();`.
* Текстовая строка, содержащая дату и время в следующем формате: "Месяц день, год часы:минуты:секунды". Например: `var Xmas95 = new Date("December 25, 1995 13:30:00")`. Если не указать секунды, минуты или часы, то их значение будет принято за 0.
* Набор целочисленных значений для года, месяца и дня. Например: `var Xmas95 = new Date(1995, 11, 25)`.
* Набор целочисленных значений для года, месяца, дня, часов, минут и секунд. Например: `var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);`.
### Получение даты в русскоязычном формате
```

new Date().toLocaleString('ru',
  {
    day: 'numeric',
    month: 'long',
    year: 'numeric'
  });
// текущая дата в формате: '10 января 2019 г.'
```

Подробнее про метод toLocalString

### Методы объекта `Date`

Методы объекта `Date` для работы с датой и временем делятся на следующие категории:

* "set" методы, служат для установки параметров объекта `Date`.
* "get" методы, служат для получения параметров объекта `Date`.
* "to" методы, служат для получения значения объекта `Date` в текстовом виде.
* "parse" и UTC методы, служат для распознавания дат и времени из текстового формата.

При помощи методов групп "get" и"set", вы можете получить и установить значения секунд, минут, часов, дня месяца, дня недели, месяца и года по отдельности. Отдельно выделим метод `getDay`, который возвращает день недели, однако соответствующего ему метода `setDay` не существует, потому-что день недели высчитывается автоматически. Все эти методы используют в своей работе целочисленные значения по следующим правилам:

* Секунды и минуты: от 0 до 59
* Часы: от 0 до 23
* Дни недели: от 0 (Воскресенье) до 6 (Суббота)
* Дни месяца: от 1 до 31
* Месяцы: от 0 (Январь) до 11 (Декабрь)
* Год: год относительно 1900 года.

Например, предположим, что вы определили дату следующим образом:

```js
var Xmas95 = new Date("December 25, 1995");
```

Тогда `Xmas95.getMonth()` вернёт 11, а `Xmas95.getFullYear()` вернёт 1995.

Методы `getTime` и `setTime могут быть` полезны при сравнении дат. Метод `getTime` возвращает количество миллисекунд, прошедших с 00:00:00 1 Января, 1970 года.

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

```js
var today = new Date(); // Получаем текущую дату
var endYear = new Date(1995, 11, 31, 23, 59, 59, 999); // Устанавливаем месяц и день на конец года
endYear.setFullYear(today.getFullYear()); // Устанавливаем текущий год
var msPerDay = 24 \* 60 \* 60 \* 1000; // Количество миллисекунд в одних сутках
var daysLeft = (endYear.getTime() - today.getTime()) / msPerDay;
var daysLeft = Math.round(daysLeft); // возвращает количество дней, оставшихся до конца года
```

Этот пример создаёт объект `Date` названный `today, который содержит текущую дату и время`. Затем, создаётся вспомогательный `Date` объект, названный `endYear,` которому устанавливаются значения, указывающие на конец года. После этого, при помощи рассчитанного количества миллисекунд в сутках, вычисляется количество дней между `today` и `endYear`, При этом используются метод `getTime` и округление, для получения количества полных дней.

Метод `parse` полезен для присвоения значений существующим объектам `Date` из текстового формата. Например, следующий код использует методы `parse` и `setTime` чтобы установить значение переменной `IPOdate`:

```js
var IPOdate = new Date();
IPOdate.setTime(Date.parse("Aug 9, 1995"));
```

### Пример

В следующем примере приведена функция `JSClock(), которая возвращает время в формате электронных часов:`

```js
function JSClock() {
  var time = new Date();
  var hour = time.getHours();
  var minute = time.getMinutes();
  var second = time.getSeconds();
  var temp = "" + (hour > 12 ? hour - 12 : hour);
  if (hour == 0) temp = "12";
  temp += (minute < 10 ? ":0" : ":") + minute;
  temp += (second < 10 ? ":0" : ":") + second;
  temp += hour >= 12 ? " P.M." : " A.M.";
  return temp;
}
```

Первым делом, функция JSClock создаёт новый объект `Date`, названный `time`; так как объект создаётся баз параметров, переменная `time` содержит текущую дату и время. Затем вызываются методы `getHours`, `getMinutes` и `getSeconds`, чтобы установить значения переменным `hour`, `minute` и `second`.

Следующие четыре выражения строят текстовую строку на основе time. Первое из них создаёт переменную `temp`, присваивая ей значение при помощи условия; Если `hour` больше чем 12, то (`hour - 12`), иначе просто `hour.` В случае же, когда `hour` равно 0, берётся фиксированное значение "12".

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

В завершение всего, последнее условное выражение добавляет строку "P.M." к переменной `temp` если `hour` равно или больше 12, иначе, добавляется строка "A.M.".

* « Предыдущая статья
* Следующая статья »


Форматирование текста - JavaScript

Форматирование текста
=====================

* « Предыдущая статья
* Следующая статья »

В этой главе приводится порядок работы со строками и текстом в JavaScript.

Строки
------

Строки используются для представления текстовых данных. Каждая строка - это набор "элементов", а каждый элемент - 16 битное беззнаковое целое значение. Элементы имеют определённые позиции. Так первый элемент имеет индекс 0, следующий - 1, и так далее. Длина строки - это количество элементов в ней. Вы можете создать строки, используя строковые литералы или объекты класса String.

### Строковые литералы

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

```js
'foo';
"bar";
```

Начиная со стандарта ES6 (ES-2015) для простых и сложных строк можно использовать обратные косые кавычки, а также, вставлять значения:

```js
const name = "Alex";
const str = `Привет, ${name},
 как дела?`;

console.log(str);
// Привет, Alex,
// как дела?
```

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

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

#### Шестнадцатеричные экранированные последовательности

Число после \x трактуется как шестнадцатеричное.

```js
"\xA9"; // "©"
```

#### Unicode экранированные последовательности

Экранированные последовательности Unicode требуют по меньшей мере 4 символа после `\u`.

```js
"\u00A9"; // "©"
```

#### Экранирование элементов кода Unicode

Нововведение ECMAScript 6, которое позволяет экранировать каждый Unicode символ, используя шестнадцатеричные значения (вплоть до `0x10FFFF`). С простым экранированием Unicode обычно требуется писать связанные друг с другом части по - отдельности для получения того же результата.

Смотрите также `String.fromCodePoint()` или `String.prototype.codePointAt()`.

```js
"\u{2F804}";

// То же самое с простым Unicode
"\uD87E\uDC04";
```

### Объекты String

Объект ``String`` - это обёртка вокруг примитивного строкового типа данных.

```js
var s = new String("foo"); // Создание объекта
console.log(s); // Отобразится: { '0': 'f', '1': 'o', '2': 'o'}
typeof s; // Вернёт 'object'
```

Вы можете вызвать любой метод объекта класса `String` на строковом литерале - JavaScript сам преобразует строковый литерал во временный объект `String`, вызовет требуемый метод и затем уничтожит этот временный объект. Со строковыми литералами вы также можете использовать и `String.length` свойство.

Следует использовать строковые литералы до тех пор, пока вам действительно не обойтись без `String` объекта, потому что, порой, объект String может вести себя неожиданно (не так, как строковый литерал). Например:

```js
var s1 = "2 + 2"; // Создание строкового литерала
var s2 = new String("2 + 2"); // Создание String объекта
eval(s1); // Вернёт 4
eval(s2); // Вернёт строку "2 + 2"
```

Объект `String` имеет свойство `length`, которое обозначает количество символов в строке. Например, в следующем коде x получит значение 13 потому, что "Hello, World!" содержит 13 символов, каждый из которых представлен одним кодом UTF-16. Вы можете обратиться к каждому коду с помощью квадратных скобок. Вы не можете изменять отдельные символы строки, т.к. строки это массива-подобные неизменяемые объекты:

```js
var mystring = "Hello, World!";
var x = mystring.length;
mystring[0] = "L"; // Ничего не произойдёт, т.к. строки неизменяемые
mystring[0]; // Вернёт: "H"
```

Объект `String` имеет множество методов, в том числе и те, которые возвращают преобразованную исходную строку (методы `substring`, `toUpperCase` и другие).

В таблице ниже представлены методы String объекта.

| Метод | Описание |
| --- | --- |
| `charAt`, `charCodeAt`, `codePointAt` | Возвращает символ или символьный код в указанной позиции в строке. |
| `indexOf`, `lastIndexOf` | Возвращает первую (indexOf) или последнюю (lastIndexOf) позицию указанной подстроки в строке. Если данная подстрока не найдена, то возвращает -1. |
| `startsWith`, `endsWith`, `includes` | Проверяет, начинается/кончается/содержит ли строка указанную подстроку. |
| `concat` | Объединяет две строки и возвращает результат в качестве новой строки. |
| `fromCharCode`, `fromCodePoint` | Создаёт строку из указанной последовательности Unicode значений. Это метод класса String, а не отдельного экземпляра этого класса. |
| `split` | Разбивает строку на подстроки, результат возвращает в виде массива строк. |
| `slice` | Извлекает часть строки и возвращает её в качестве новой строки. |
| `substring`, `substr` | Возвращает указанную часть строки по начальному и конечному индексам, либо по начальному индексу и длине. |
| `match`, `replace`, `search` | Работа с регулярными выражениями. |
| `toLowerCase`, `toUpperCase` | Возвращает строку полностью в нижнем (toLowerCase) или верхнем (toUpperCase) регистре. |
| `normalize` | Возвращает нормализованную Unicode форму строки - значения объекта String, на котором вызывается. |
| `repeat` | Возвращает строку, которая представляет собой повторение исходной строки указанное количество раз. |
| `trim` | Убирает пробелы в начале и в конце строки, результат возвращается в качестве новой строки. |

### Многострочные шаблонные строки

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

Такого типа строки заключаются в пару обратных штрихов (` `) (grave accent) вместо двойных или одинарных кавычек. Шаблонные строки могут содержать заполнители, которые выделяются знаком доллара и фигурными скобками (`${выражение}`).

#### Многострочная запись

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

```js
console.log(
  "string text line 1\n\
string text line 2",
);
// "string text line 1
// string text line 2"
```

Того же результата можно добиться и другим способом (используя синтаксис шаблонных строк):

```js
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
```

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

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

```js
var a = 5;
var b = 10;
console.log("Fifteen is " + (a + b) + " and\nnot " + (2 \* a + b) + ".");
// "Fifteen is 15 and
// not 20."
```

Теперь же, используя шаблонные строки, вы можете сделать это так:

```js
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 \* a + b}.`);
// "Fifteen is 15 and
// not 20."
```

Для более подробной информации смотри Шаблонные строки в справочнике по JavaScript.

Интернационализация
-------------------

Объект `Intl` представляет собой пространство имён для ECMAScript API по интернационализации, которое обеспечивает чувствительное к языку сравнение строк, форматирование чисел, времени и даты. Конструкторы для объектов `Collator`, `NumberFormat` и `DateTimeFormat` являются свойствами `объекта Intl`.

### Форматирование времени и даты

Объект `DateTimeFormat` полезен для форматирования времени и даты. В примере ниже дата форматируется так, как это принято в США (результат отличен для разных временных зон).

```js
var msPerDay = 24 \* 60 \* 60 \* 1000;

// July 17, 2014 00:00:00 UTC.
var july172014 = new Date(msPerDay \* (44 \* 365 + 11 + 197));

var options = {
  year: "2-digit",
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
  timeZoneName: "short",
};
var americanDateTime = new Intl.DateTimeFormat("en-US", options).format;

console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
```

### Форматирование чисел

Объект `NumberFormat` полезен при форматировании чисел, например, валют.

```js
var gasPrice = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 3,
});

console.log(gasPrice.format(5.259)); // $5.259

var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec", {
  style: "currency",
  currency: "CNY",
});

console.log(hanDecimalRMBInChina.format(1314.25)); // ￥ 一,三一四.二五
```

### Сравнение

Объект `Collator` полезен для сравнения и сортировки строк.

Например, в Германии есть два различных порядка сортировки строк в зависимости от документа: телефонная книга или словарь. Сортировка по типу телефонной книги подчёркивает звуки.

```js
var names = ["Hochberg", "Hönigswald", "Holzman"];

var germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk");

// as if sorting ["Hochberg", "Hoenigswald", "Holzman"]:
console.log(names.sort(germanPhonebook.compare).join(", "));
// logs "Hochberg, Hönigswald, Holzman"
```

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

```js
var germanDictionary = new Intl.Collator("de-DE-u-co-dict");

// as if sorting ["Hochberg", "Honigswald", "Holzman"]:
console.log(names.sort(germanDictionary.compare).join(", "));
// logs "Hochberg, Holzman, Hönigswald"
```

Для более подробной информации об `Intl` API смотри Introducing the JavaScript Internationalization API.

Регулярные выражения
--------------------

Регулярные выражения - это шаблоны, которые используются для описания некоторого множества строк . Это очень мощный и в некоторый степени непростой механизм, и поэтому ему посвящена отдельная глава. Узнать больше о регулярных выражениях можно здесь:

* Регулярные выражения JavaScript в руководстве по JavaScript.
* `RegExp` ссылка в документации.
* « Предыдущая статья
* Следующая статья »


Коллекции - JavaScript

Коллекции
=========

* « Предыдущая статья
* Следующая статья »

Этот раздел содержит обзор коллекций `Set` и словарей `Map` (en-US) - встроенных структур данных с доступом по ключу.

Словари
-------

### `Тип Map`

`Map` (en-US) - реализация простого ассоциативного массива (словаря). Он содержит данные в виде набора пар ключ/значение(ключи уникальны) и предоставляет методы для доступа и манипулирования этими данными.

Также как и объект, словарь позволяет

* получать значение по ключу, а также проверять наличие ключа
* добавлять/удалять пары ключ/значение
* перезаписывать значение по ключу (ключи уникальны).
* итерироваться по ключам

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

* Ключи словаря могут быть любого типа (а не только строки).
* Словарь хранит свой размер (не надо вычислять).
* Натуральный порядок обхода элементов ( в порядке добавления) с помощью `for...of`.
* Словарь не подмешивает ключи из прототипа (в отличие от объекта).

В следующем примере приведены основные операции со словарём:

```js
var sayings = new Map();
sayings.set("dog", "woof");
sayings.set("cat", "meow").set("elephant", "toot");
//вызов функции .set возвращает Map, поэтому set можно объединять в цепочки

sayings.set("dog", "гав-гав"); // заменить значение по ключу

sayings.size; // 3
sayings.get("fox"); // undefined
sayings.has("bird"); // false
sayings.delete("dog");

for (var [key, value] of sayings) {
  console.log(key + " goes " + value);
}
// "cat goes meow"
// "elephant goes toot"
```

Больше примеров и полное описание на странице справочника `Map` (en-US) .

### `Тип WeakMap`

`WeakMap` это специальный вид словаря, **ключами которого могут быть только объекты**, причём ссылки на них в WeakMap являются *слабыми* (не учитываются сборщиком мусора (garbage collector GC)).

**Примечание:** Интерфейс `WeakMap` совпадает с `Map`, единственное отличие - **ключи `WeakMap` нельзя итерировать** (т.e. нельзя получить список ключей). Это понятно, поскольку в таком случае возникла бы неопределённость с достоверностью этого списка в зависимости от состояния garbage collection.

Больше примеров, полное описание, а также обсуждение "Зачем *WeakMap*?" на странице справочника `WeakMap`.

Отметим, что `WeakMap,` в частности, может элегантно использоваться для упаковки приватных данных или деталей реализации. Следующий пример из статьи Nick Fitzgerald "Hiding Implementation Details with ECMAScript 6 WeakMaps". Приватная часть сохраняется как значение в `privates` и имеет время жизни такое же как и сущность класса. Сам класс и его методы публичны; прочее недоступно извне модуля:

```js
const privates = new WeakMap();

export class Public() {

  constructor() {
    const me = {
    // Приватные данные идут здесь
    };
    // 'me' будет освобождён вместе с 'this' !!!
    privates.set(this, me);
  }

  method () {
    const me = privates.get(this);
    // Сделайте что-нибудь с приватными данными в 'me'...
  }
}
```

Коллекции
---------

### `Тип Set`

`Set` реализация коллекции - структура данных, которая содержит список уникальных элементов в порядке их добавления.

В следующем примере приведены основные операции по работе с коллекцией `Set:`

```js
var mySet = new Set();
mySet.add(1);
mySet.add("some text");
mySet.add("foo");

mySet.has(1); // true
mySet.delete("foo");
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"
```

Больше примеров и полное описание на странице справочника `Set`

#### Преобразования между Array и Set

Можно создать `Array` из Set с помощью `Array.from` или используя spread operator.

В свою очередь, конструктор `Set` может принимать `Array` в качестве аргумента.

**Примечание:** Поскольку `Set` структура работает с уникальными значениями, любые повторяющиеся элементы из Array будут проигнорированы.

```js
Array.from(mySet);
[...mySet2];

mySet2 = new Set([1, 2, 3, 4]);
```

#### `Сравнение Array` и `Set`

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

* `Set.has` работает быстрее чем `Array.indexOf`.
* можно удалять элементы по значению (а не по индексу как массивах).
* `NaN` обрабатывается корректно.
* поддерживается уникальность значений.
### `Тип WeakSet`

`WeakSet` это специальный вид коллекции, элементами которой могут быть только объекты. Ссылки на эти объекты в WeakSet являются *слабыми* (не учитываются сборщиком мусора (garbage collector GC)).

**Примечание:** Элементы `WeakSet` уникальны и могут быть добавлены только один раз, также как и в `Set`.

Основные отличия от `Set`:

* `WeakSet` это коллекция *объектов* ( примитивные значения не могут быть добавлены).
* `WeakSet` *нельзя итерировать*. А также нельзя получить список (итератор) элементов.

Использование `WeakSet` достаточно специфическое. Пользуясь тем, что они не могут создавать утечек памяти, в них можно, например, безопасно помещать ссылки на DOM-элементы.

Больше примеров и полное описание на странице справочника `WeakSet`

Проверка на равенство в `Map` и `Set`
-------------------------------------

Сравнение на равенство ключей в `Map` objects или объектов в `Set` основано на "same-value-zero algorithm":

* алгоритм сравнения в целом совпадает с оператором `===`.
* `-0` и `+0` считаются равными (в отличие от `===`).
* `NaN` считается равным самому себе (в отличие от `===`).
* « Предыдущая статья
* Следующая статья »


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

Введение в JavaScript
=====================

* « Предыдущая статья
* Следующая статья »

Данная глава является введением в JavaScript и рассматривает некоторые его фундаментальные концепции.

Что вам уже следует знать?
--------------------------

В данном руководстве предполагается, что вы имеете:

* Общее понимание Internet и World Wide Web (WWW (en-US)).
* Хорошее знание HyperText Markup Language (HTML).
* Некоторый опыт программирования. Если вы являетесь новичком в программировании, то ознакомьтесь с руководствами, приведёнными на странице по JavaScript.
Где можно найти информацию о JavaScript?
----------------------------------------

Документация по JavaScript на MDN включает:

* Изучение Web предоставляет информацию для начинающих и вводит в базовые концепции программирования и Internet.
* Руководство по JavaScript (данное руководство) предоставляет обзор JavaScript и его объектов.
* Справочник по JavaScript предоставляет подробную информацию по JavaScript.

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

Что такое JavaScript?
---------------------

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

JavaScript включает стандартную библиотеку объектов, например, `Array`, `Date` и `Math`, а также базовый набор языковых элементов, например, операторы и управляющие конструкции. Ядро JavaScript может быть расширено для различных целей путём добавления в него новых объектов, например:

* JavaScript на стороне клиента расширяет ядро языка, предоставляя объекты для контроля браузера и его Document Object Model (DOM). Например, клиентские расширения позволяют приложению размещать элементы в форме HTML и обрабатывать пользовательские события, такие как щелчок мыши, ввод данных в форму и навигация по страницам.
* JavaScript на стороне сервера расширяет ядро языка, предоставляя объекты для запуска JavaScript на сервере. Например, расширение на стороне сервера позволяет приложению соединяться с базой данных, обеспечивать непрерывность информации между вызовами приложения или выполнять манипуляции над файлами на сервере.
JavaScript и Java
-----------------

JavaScript и Java похожи в одних отношениях, но фундаментально отличны в других. Javascript напоминает Java, но не имеет статической типизации и строгой проверки типов, которыми обладает Java. JavaScript следует большей части синтаксиса Java в выражениях, соглашениях об именовании и основного потока управления конструкциями, поэтому он был переименован из LiveScript в JavaScript.

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

По сравнению с Java, JavaScript является языком с очень свободной формой. Вам не надо объявлять переменные, классы и методы. Вам не надо беспокоиться о том, являются ли методы публичными (public), приватными (private) или защищёнными (protected), а также вам не надо реализовывать интерфейсы. Переменные, параметры и возвращаемые функциями типы не являются явно типизированными.

Java — это язык программирования, основанный на классах и предназначенный для быстрого выполнения и безопасности типов. Безопасность типов означает, например, что вы не можете привести тип integer к типу object reference или получить доступ к приватной памяти, изменяя байт-код Java. Ориентированная на классы модель Java означает, что программы состоят исключительно из классов и их методов. Наследование классов и строгая типизация в Java обычно требуют тесно связанные иерархии объектов. Эти требования делают программирование на Java более комплексным, чем программирование на JavaScript.

По духу JavaScript происходит от небольших, динамически типизированных языков, таких как HyperTalk и dBASE. Эти скриптовые языки предлагают инструменты программирования для гораздо более широкой аудитории благодаря более простому синтаксису, специализированной встроенной функциональности и минимальным требованиям для создания объектов.

| JavaScript | Java |
| --- | --- |
| Объектно-ориентированный. Нет различий между типами объектов. Наследование реализовано через механизм прототипов, свойства и методы могут быть добавлены в любой объект динамически. | На базе классов. Объекты делятся на классы и экземпляры с наследованием через классовую иерархию. Классы и экземпляры не могут иметь динамически добавленные свойства или методы. |
| Типы данных переменных не объявляются (динамическая типизация). | Типы данных переменных должны быть объявлены (статическая типизация). |
| Не может автоматически записывать на жёсткий диск. | Может автоматически записывать на жёсткий диск. |

Для получения дополнительной информации о различиях между JavaScript и Java, прочитайте Details of the object model (en-US).

JavaScript и спецификация ECMAScript
------------------------------------

JavaScript стандартизирован европейской ассоциацией Ecma International, деятельность которой посвящена стандартизации информационных и коммуникационных систем (изначально ECMA являлся акронимом European Computer Manufacturers Association). Эта стандартизированная версия JavaScript, называемая ECMAScript, работает одинаково во всех приложениях, поддерживающих стандарт. Компании могут использовать открытый стандарт языка, чтобы разработать собственную реализацию JavaScript. Стандарт ECMAScript задокументирован в спецификации ECMA-262.

Стандарт ECMA-262 также утверждён ISO (International Organization for Standardization) как ISO-16262. Вы можете найти спецификацию на сайте Ecma International. Спецификация ECMAScript не описывает Document Object Model (DOM), которая стандартизирована World Wide Web Consortium (W3C). DOM определяет способ для доступа к объектам HTML документа из вашего скрипта. Чтобы получить более точное представление о различных технологиях, используемых при программировании на JavaScript, прочитайте Обзор JavaScript.

### Документация JavaScript против спецификации ECMAScript

Спецификация ECMAScript — это набор требований, касающихся реализации ECMAScript. Она предназначена для реализации языковых возможностей, соответствующих стандарту, в вашей реализации ECMAScript или движке (например, SpiderMonkey в Firefox или V8 в Google Chrome).

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

Спецификация ECMAScript использует терминологию и синтаксис, которые могут быть незнакомы JavaScript-программистам. Хотя описание языка может отличаться в ECMAScript, но сам язык остаётся таким же. JavaScript поддерживает всю функциональность, описанную в спецификации ECMAScript.

Документация JavaScript описывает аспекты языка, являющиеся подходящими для JavaScript-программиста.

Начинаем знакомство с JavaScript
--------------------------------

Все, что вам нужно для знакомства с JavaScript — это современный браузер. Данное руководство включает некоторые возможности JavaScript, которые на данный момент доступны только в последних версиях Firefox, поэтому рекомендуется использовать последнюю версию Firefox.

В Firefox встроены два инструмента, полезных для экспериментирования с JavaScript: Web Console и Scratchpad.

### Web Console

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

Чтобы открыть Web Console, выберите "Web Console" из меню "Web Developer", которое находится под меню "Tools" в Firefox. Консоль появится в нижней части окна браузера. Вдоль нижней части консоли размещается командная строка, которую вы можете использовать для ввода JavaScript, результат выполнения появится на панели выше:

![](/ru/docs/Web/JavaScript/Guide/Introduction/2019-04-04_00-15-29.png)
```

function greetMe(yourName) {
  alert('Hello ' + yourName);
}
console.log(eval('3 + 5'));
```

### Scratchpad

Web Console отлично подходит для выполнения одиночных строк JavaScript, но хотя вы можете выполнить и несколько строк, это не очень удобно, к тому же вы не можете сохранить ваш код, используя Web Console. Поэтому для более комплексных примеров Scratchpad является более подходящим инструментом.

Чтобы открыть Scratchpad(`Shift`+`F4`), выберите "Scratchpad" из меню "Web Developer", которое находится под меню "Tools" в Firefox. Блокнот будет открыт в отдельном окне, вы можете использовать его для создания и выполнения JavaScript в браузере. Вы также можете сохранять ваши скрипты на жёсткий диск, а потом загружать их.

Если вы выберете "Display", то код в вашем блокноте будет выполнен в браузере, а результат вставлен обратно в блокнот как комментарий:

![](/ru/docs/Web/JavaScript/Guide/Introduction/scratchpad.png)

### Hello world

Чтобы начать писать JavaScript-код откройте Scratchpad и напишите свой первый "Hello World!" код:

```js
(function () {
  "use strict";
  /\* Start of your code \*/
  function greetMe(yourName) {
    alert("Hello " + yourName);
  }

  greetMe("World");
  /\* End of your code \*/
})();
```

Выберите код на панели и зажмите Ctrl + R, чтобы открыть код в браузере! На следующих страницах мы изучим синтаксис и возможности JS, чтобы вы могли написать более сложное приложение. Не забывайте добавлять перед кодом `(function(){"use strict";` и `})();` после. вы узнаете, что это означает, а пока считайте, что это —

1. Значительно улучшает производительность
2. Предотвращает структуры, которые могут запутать вас на начальном этапе.
3. Предотвращает взаимодействие фрагментов кода, выполняемых в консоли.
* « Предыдущая статья
* Следующая статья »


Использование промисов - JavaScript

Использование промисов
======================

* « Предыдущая статья (en-US)
* Следующая статья »

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

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

Например, вместо старомодной функции, которая принимает два колбэка и вызывает один из них в зависимости от успешного или неудачного завершения операции:

```js
function doSomethingOldStyle(successCallback, failureCallback) {
  console.log("Готово.");
  // Успех в половине случаев.
  if (Math.random() > 0.5) {
    successCallback("Успех");
  } else {
    failureCallback("Ошибка");
  }
}

function successCallback(result) {
  console.log("Успешно завершено с результатом " + result);
}

function failureCallback(error) {
  console.log("Завершено с ошибкой " + error);
}

doSomethingOldStyle(successCallback, failureCallback);
```

…современные функции возвращают промис, в который вы записываете ваши колбэки:

```js
function doSomething() {
  return new Promise((resolve, reject) => {
    console.log("Готово.");
    // Успех в половине случаев.
    if (Math.random() > 0.5) {
      resolve("Успех");
    } else {
      reject("Ошибка");
    }
  });
}

const promise = doSomething();
promise.then(successCallback, failureCallback);
```

…или просто:

```js
doSomething().then(successCallback, failureCallback);
```

Мы называем это *асинхронным вызовом функции*. У этого соглашения есть несколько преимуществ. Давайте рассмотрим их.

Гарантии
--------

В отличие от старомодных переданных колбэков промис даёт некоторые гарантии:

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

Но наиболее непосредственная польза от промисов - цепочка вызовов (*chaining*).

Цепочка вызовов
---------------

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

Вот в чём магия: функция `then` возвращает новый промис, отличающийся от первоначального:

```js
let promise = doSomething();
let promise2 = promise.then(successCallback, failureCallback);
```

или

```js
let promise2 = doSomething().then(successCallback, failureCallback);
```

Второй промис представляет завершение не только `doSomething()`, но и функций `successCallback` или `failureCallback`, переданных вами, а они тоже могут быть асинхронными функциями, возвращающими промис. В этом случае все колбэки, добавленные к `promise2` будут поставлены в очередь за промисом, возвращаемым `successCallback` или `failureCallback`.

По сути, каждый вызванный промис означает успешное завершение предыдущих шагов в цепочке.

Раньше выполнение нескольких асинхронных операций друг за другом приводило к классической "Вавилонской башне" колбэков:

```js
doSomething(function (result) {
  doSomethingElse(
    result,
    function (newResult) {
      doThirdThing(
        newResult,
        function (finalResult) {
          console.log("Итоговый результат: " + finalResult);
        },
        failureCallback,
      );
    },
    failureCallback,
  );
}, failureCallback);
```

В современных функциях мы записываем колбэки в возвращаемые промисы - формируем цепочку промисов:

```js
doSomething()
  .then(function (result) {
    return doSomethingElse(result);
  })
  .then(function (newResult) {
    return doThirdThing(newResult);
  })
  .then(function (finalResult) {
    console.log("Итоговый результат: " + finalResult);
  })
  .catch(failureCallback);
```

Аргументы `then` необязательны, а `catch(failureCallback)` - это сокращение для `then(null, failureCallback)`. Вот как это выражено с помощью стрелочных функций:

```js
doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => {
    console.log(`Итоговый результат: ${finalResult}`);
  })
  .catch(failureCallback);
```

**Важно:** Всегда возвращайте промисы в return, иначе колбэки не будут сцеплены и ошибки могут быть не пойманы (стрелочные функции неявно возвращают результат, если скобки {} вокруг тела функции опущены).

### Цепочка вызовов после catch

Можно продолжить цепочку вызовов *после* ошибки, т. е. после `catch`, что полезно для выполнения новых действий даже после того, как действие вернёт ошибку в цепочке вызовов. Ниже приведён пример:
```

new Promise((resolve, reject) => {
    console.log('Начало');

    resolve();
})
.then(() => {
    throw new Error('Где-то произошла ошибка');

    console.log('Выведи это');
})
.catch(() => {
    console.log('Выведи то');
})
.then(() => {
    console.log('Выведи это, несмотря ни на что');
});
```

В результате выведется данный текст:
```

Начало
Выведи то
Выведи это, несмотря ни на что
```

Заметьте, что текст "Выведи это" не вывелся, потому что "Где-то произошла ошибка" привела к отказу

Распространение ошибки
----------------------

Вы могли ранее заметить, что `failureCallback` повторяется три раза в **"pyramid of doom",** а в цепочке промисов всего лишь один раз:
```

doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(`Итоговый результат: ${finalResult}`))
.catch(failureCallback);
```

В основном, цепочка промисов останавливает выполнение кода, если где-либо произошла ошибка, и вместо этого ищет далее по цепочке обработчики ошибок. Это очень похоже на то, как работает синхронный код:
```

try {
  let result = syncDoSomething();
  let newResult = syncDoSomethingElse(result);
  let finalResult = syncDoThirdThing(newResult);
  console.log(`Итоговый результат: ${finalResult}`);
} catch(error) {
  failureCallback(error);
}
```

Эта симметрия с синхронным кодом лучше всего показывает себя в синтаксическом сахаре `async`/`await` в ECMAScript 2017:
```

async function foo() {
  try {
    let result = await doSomething();
    let newResult = await doSomethingElse(result);
    let finalResult = await doThirdThing(newResult);
    console.log(`Итоговый результат: ${finalResult}`);
  } catch(error) {
    failureCallback(error);
  }
}
```

Работа данного кода основана на промисах. Для примера здесь используется функция `doSomething()`, которая встречалась ранее. Вы можете прочитать больше о синтаксисе здесь

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

Создание промиса вокруг старого колбэка
---------------------------------------

`Promise` может быть создан с помощью конструктора. Это может понадобится только для старых API.

В идеале, все асинхронные функции уже должны возвращать промис. Но увы, некоторые APIs до сих пор ожидают успешного или неудачного колбэка переданных по старинке. Типичный пример: `setTimeout()` функция:
```

setTimeout(() => saySomething("10 seconds passed"), 10000);
```

Смешивание старого колбэк-стиля и промисов проблематично. В случае неудачного завершения `saySomething` или программной ошибки, нельзя обработать ошибку.

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

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
```

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

Композиция
----------

`Promise.resolve()` и `Promise.reject()` короткий способ создать уже успешные или отклонённые промисы соответственно. Это иногда бывает полезно.

`Promise.all()` и `Promise.race()` - два метода запустить асинхронные операции параллельно.

Последовательное выполнение композиции возможно при помощи хитрости JavaScript:
```

[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
```

Фактически, мы превращаем массив асинхронных функций в цепочку промисов равносильно: `Promise.resolve().then(func1).then(func2);`

Это также можно сделать, объединив композицию в функцию, в функциональном стиле программирования:
```

const applyAsync = (acc,val) => acc.then(val);
const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
```

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

const transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2);
transformData(data);
```

В ECMAScript 2017, последовательные композиции могут быть выполнены более простым способом с помощью async/await:
```

for (const f of [func1, func2]) {
  await f();
}
```

Порядок выполнения
------------------

Чтобы избежать сюрпризов, функции, переданные в `then` никогда не будут вызваны синхронно, даже с уже разрешённым промисом:
```

Promise.resolve().then(() => console.log(2));
console.log(1); // 1, 2
```

Вместо немедленного выполнения, переданная функция встанет в очередь микрозадач, а значит выполнится, когда очередь будет пустой в конце текущего вызова JavaScript цикла событий (event loop), т.е. очень скоро:
```

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

wait().then(() => console.log(4));
Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
console.log(1); // 1, 2, 3, 4
```

Вложенность
-----------

Простые цепочки promise лучше оставлять без вложений, так как вложенность может быть результатом небрежной структуры. Смотрите распространённые ошибки.

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

doSomethingCritical()
.then(result => doSomethingOptional()
  .then(optionalResult => doSomethingExtraNice(optionalResult))
  .catch(e => {})) // Игнорируется если необязательные параметр не выкинул исключение
.then(() => moreCriticalStuff())
.catch(e => console.log("Критическая ошибка: " + e.message));
```

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

Внутренний оператор catch нейтрализует и перехватывает ошибки только от doSomethingOptional() и doSomethingExtraNice(), после чего код возобновляется с помощью moreCriticalStuff(). Важно, что в случае сбоя doSomethingCritical() его ошибка перехватывается только последним (внешним) catch.

Частые ошибки
-------------

В этом разделе собраны частые ошибки, возникающие при создании цепочек промисов. Несколько таких ошибок можно увидеть в следующем примере:
```

// Плохой пример! Три ошибки!

doSomething().then(function(result) {
  doSomethingElse(result) // Забыл вернуть промис из внутренней цепочки + неуместное влаживание
  .then(newResult => doThirdThing(newResult));
}).then(() => doFourthThing());
// Забыл закончить цепочку методом catch
```

Первая ошибка это неправильно сцепить вещи между собой. Такое происходит когда мы создаём промис но забываем вернуть его. Как следствие, цепочка сломана, но правильнее было бы сказать что теперь у нас есть две независимые цепочки, соревнующиеся за право разрешится первой. Это означает, что `doFourthThing()` не будет ждать `doSomethingElse()` или `doThirdThing()` пока тот закончится, и будет исполнятся параллельно с ними, это, вероятно, не то что хотел разработчик. Отдельные цепочки также имеют отдельную обработку ошибок, что приводит к необработанным ошибкам.

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

Третья ошибка это забыть закончить цепочку ключевым словом `catch`. Незаконченные цепочки приводят к необработанным отторжениям промисов в большинстве браузеров.

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

doSomething()
.then(function(result) {
  return doSomethingElse(result);
})
.then(newResult => doThirdThing(newResult))
.then(() => doFourthThing())
.catch(error => console.log(error));
```

Обратите внимание что `() => x` это сокращённая форма `() => { return x; }`.

Теперь у нас имеется единственная определённая цепочка с правильной обработкой ошибок.

Использование `async`/`await` предотвращает большинство, если не все вышеуказанные ошибки, но взамен появляется другая частая ошибка — забыть ключевое слово `await`.

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

* `Promise.then()`
* Спецификация Promises/A+ (EN)
* Нолан Лоусон (Nolan Lawson): У нас проблемы с промисами - распространённые ошибки (EN)


Классы символов - JavaScript

Классы символов
===============

Классы символов позволяют различать виды символов, к примеру, как различия между буквами и цифрами.

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

Типы
----

| Символ | Значение |
| --- | --- |
| `.` | Точка имеет одно из следующих смыслов:* Совпадение с любым одним символом *за исключение* символов
 завершения строки: `\n`, `\r`,
 `\u2028` or `\u2029`. Например,
 `/.y/` совпадает "my" с "ay", и не совпадает с "yes" и
 "yes make my day".
* В набор символов, точка теряет свой специальный смысл и совпадает с
 литеральным символом точка.

 Замечание. `m` флаг поиска по множеству строк не меняет
 поведения точки. Чтобы найти воспаления во многострочном поиске можно
 использовать набор символов `[^]` — он совпадает с любым
 символом включая символы завершения строки.

 В ES2018 добавили `s` "dotAll" флаг, который позволяет
 точке `(.`) находить все символы включая символы переноса
 строк.
  |
| `\d` |
 Совпадёт с любой цифрой (арабский числа). Эквивалентно
 `[0-9]`. Например, `/\d/` или
 `/[0-9]/` находит "2" в "B2 is the suite number"..
  |
| `\D` |
 Совпадёт с любым символом, который не является цифрой (арабский
 числа). Эквивалентно `[^0-9]`. Например,
 `/\D/` or `/[^0-9]/` находит "B" в "B2 is the
 suite number".
  |
| `\w` |
 Совпадёт с любой буквенно-числовым символом из базового латинского
 алфавита включая нижнее подчёркивание. Эквивалентно
 `[A-Za-z0-9_]`. Например, `/\w/` находит "a" в
 "apple", "5" в "$5.28", "3" в "3D" и "m" в "Émanuel".
  |
| `\W` |
 Совпадёт с любой буквенно-числовым, которое не является символом
 базового латинского алфавита, так же исключая нижнее подчёркивание.
 Эквивалентно `[^A-Za-z0-9_]`. Например,
 `/\W/` или `/[^A-Za-z0-9_]/` находит "%" в "50%"
 и "É" in "Émanuel".
  |
| `\s` |
 Совпадёт с любым пробельным символом, включая пробел, символ
 табуляции, символ подачи страницы, символ подачи строки и другие
 Unicode пробелы. Эквивалентно
 `[
\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]`. Например, `/\s\w*/` находит " bar" в "foo bar".
  |
| `\S` |
 Совпадёт с любым символом, не являющимся пробельным. Эквивалентно
 `[^
\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]`. Например, `/\S\w*/` находит "foo" в "foo bar".
  |
| `\t` | Совпадёт с символом горизонтальной табуляции. |
| `\r` | Совпадёт с символом возврата каретки. |
| `\n` | Совпадёт с символом подачи строки. |
| `\v` | Совпадёт с символом вертикальной табуляции |
| `\f` | Совпадёт с символом подачи страницы (формы). |
| `[\b]` |
 Совпадёт с символом возврат назад (англ. backspace). Если вы ищите
 символ границы слова (`\b`), смотри
 Границы.
  |
| `\0` | Совпадёт с символом NUL character. Не используйте другую цифру. |
| `\c*X*` |
 Совпадёт с контрольным символом using
 каретную нотацию, где "X" буква A–Z (соответствует кодам `U+0001`*–*`U+001F`). For example, `/\cM/` matches "\r" in
 "\r\n".
  |
| `\x*hh*` |
 Совпадёт с символом, код которого `*hh*` (две
 шестнадцатеричных цифры).
  |
| `\u*hhhh*` |
 Совпадёт с код-блоком UTF-16 со значением
 `*hhhh*` (четыре шестнадцатеричных цифры).
  |
| `\u*{hhhh}* or *\u{hhhhh}*` |
 (Только когда установлен флаг `u`.) Совпадёт с Unicode
 символом со значением `U+*hhhh*` или
 `U+*hhhhh*` (шестнадцатеричные цифры).
  |
| `\` |
 Определяет что последующий символ должен быть интерпретирован по
 особому или должен быть "экранирован. Это работает в двух вариантах:
 * Для символов, которые относятся к литералам, последующий символ -
 это специальный символ, который не должен быть интерпретирован, как
 литерал. Например, `/b/` совпадает с символом "b".
 Установ обратного слеша перед "b". Таким образом `/\b/`.
 Будет означать символ границы слова.
* Для символов, которые относятся к специальным, определяет что это не
 специальным символ, а должен быть интерпретирован, как литерал.
 Например, `*` - это специальный символ, который означает
 0 или любое другое совпадений предыдущего символа, Например
 `/a*/` совпадает с любым количеством символов "a" идущих
 подряд (или 0 "a") `a, aaaa, aaaaaa`. Если специальный
 символ `*`, как литерал, то перед ним ставится обратных
 слеш. Например, `/a\*/` совпадает только с "a\*".

 Чтобы найти литеральное совпадение с этим символов (`\` ,
 экранируйте его самим же. Другими словами для поиска
 `\` используйте `/\\/`.

 |

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

### Поиск серии цифр

```js
var randomData = "015 354 8787 687351 3512 8735";
var regexpFourDigits = /\b\d{4}\b/g;
// \b определяет границу поиска (например, не начинает поиск с середины слова)
// \d{4} определяет цифру, четыре раза
// определяет другую границу поиска (например, не начинает поиск с середины слова)

// Вывод всех чисел имеющих только 4 цифры
console.table(randomData.match(regexpFourDigits));
// ['8787', '3512', '8735']
```

### Поиск слов (латинский алфавит), начинающих с A

```js
var aliceExcerpt =
  "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
var regexpWordStartingWithA = /\b[aA]\w+/g;
// \b определяет границу поиска (например, не начинает поиск с середины слова)
// [aA] определяет букву a или A
// \b определяет границу поиска (например, не начинает поиск с середины слова)

console.table(aliceExcerpt.match(regexpWordStartingWithA));
// ['Ada', 'and', 'at', 'all']
```

### Поиски слов (из Unicode символов)

Вместо латинского алфавита, мы может использовать диапазон Unicode символов для определения слова (благодаря этому мы можем работать с текстами написанным, например на русском или арабском языке or Arabic). Unicode содержит большинство символов используемых на планете, мы так же можем объединять их диапазоны и классы символов.

```js
var nonEnglishText = "Приключения Алисы в Стране чудес";
var regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
// BMP goes through U+0000 to U+FFFF but space is U+0020

console.table(nonEnglishText.match(regexpBMPWord));
["Приключения", "Алисы", "в", "Стране", "чудес"];
```

Смотрите по теме
----------------

* Руководство по Regular expressions
    + Assertions
    + Quantifiers (en-US)
    + Unicode property escapes (en-US)
    + Groups and ranges (en-US)
* Конструктор `RegExp()`


Assertions - JavaScript

Assertions
==========

Проверка (assertion) задаёт возможность совпадения одним из указанных способов. Проверка может содержать условные выражения, опережающие (look-ahead) и ретроспективные (look-behind) проверки.

Типы
----

**Примечание:** Символ `?` также может быть использован как обычный квантификатор.

| Выражение | Что означает |
| --- | --- |
| x(?=y) | **Опережающая проверка:** `x` подходит только когда за `x` следует `y`. Например, /`Jack(?=Sprat)/` сработает для "Jack" только когда за ним будет "Sprat". `/Jack(?=Sprat|Frost)/` подойдёт для "Jack" только когда за ним будет "Sprat" или "Frost". Следует заметить, что ни "Sprat" ни "Frost" не будут выданы как часть проверки. |
| x(?!y) | **Отрицательная опережающая проверка:** `x` подходит только когда за `x` не следует `y`. Например, `/\d+(?!\.)/` сработает для числа в том случае, если за ним не стоит точка. Выполнение кода `/\d+(?!\.)/.exec('3.141')` выдаст только число "141", поскольку за "3" следует точка. |
| (?<=y)x | **Ретроспективная проверка:** `x` подходит только когда `x` предшествует `y`. Например, `/(?<=Jack)Sprat/` сработает для "Sprat" только если перед ним есть "Jack". `/(?<=Jack|Tom)Sprat/` подойдёт для "Sprat" если перед ним будут "Jack" или "Tom". Заметим, что ни "Jack" ни "Tom" не будут выданы. |
| (?<!y)x | **Отрицательная ретроспективная проверка:** `x` подходит только когда `x` не предшествует `y`. Например, `/(?<!-)\d+/` сработает для числа в том случае, если перед ним не стоит знак минус. Выполнение кода `/(?<!-)\d+/.exec('3')` выдаст "3". Код `/(?<!-)\d+/.exec('-3')` ничего не найдёт, т.к. перед числом есть знак минус. |

Examples
--------

Browser support
---------------

See also
--------


Floor

Floor
=====

**XSLT/XPath Reference**: XSLT elements, EXSLT functions, XPath functions, XPath axes

Функция `floor` принимает десятичное число и возвращает наибольшее целое, меньшее или равное исходному.

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

floor( number )
```

### Аргументы

`number`

Десятичное число

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

Ближайшее целое, меньшее или равное `number`.

### Определено

XPath 1.0 4.4

### Поддержка Gecko

Поддерживается


Как сделать PWA устанавливаемым - Прогрессивные веб-приложения

Как сделать PWA устанавливаемым
===============================

* Назад  (en-US)
* Обзор: Progressive (en-US)
* Далее  (en-US)

В предыдущей статье мы читали о том, как js13kPWA работает в off-line режиме благодаря service worker, но мы можем пойти дальше и позволить устанавливать веб-приложения на поддерживающие мобильные браузеры, как если бы это было нативное приложение. В этой статье разберём, как этого добиться, используя веб-манифест и функцию под названием «Добавить на главный экран».

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

Требования
----------

Чтобы сделать сайт доступным для установки, ему необходимы следующие вещи:

* Веб-манифест с правильно заполненными полями
* Сайт должен использовать защищённый (HTTPS) домен
* Иконка для предоставления приложения на устройстве
* Зарегистрированный service worker, чтобы приложение работало в off-line режиме (на данный момент требуется только для Chrome на Android)
### Файл манифеста

Ключевым элементом является файл манифеста, в котором представлена вся информация о веб-сайте в JSON формате.

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

Файл `js13kpwa.webmanifest` веб-приложения js13kPWA включён в раздел `<head>` файла `index.html` с помощью следующей строчки кода:

```html
<link rel="manifest" href="js13kpwa.webmanifest" />
```

**Примечание:** Существует несколько расширений, используемых в прошлом: `manifest.webapp` был популярен в манифестах приложений Firefox OS, также многие используют `manifest.json` потому что содержание организовано по структуре JSON. Однако, расширение `.webmanifest` явно упоминается в W3C manifest specification, поэтому давайте придерживаться именно этого стандарта.

Содержимое файла может выглядеть так:

```json
{
  "name": "js13kGames Progressive Web App",
  "short\_name": "js13kPWA",
  "description": "Progressive Web App that lists games submitted to the A-Frame category in the js13kGames 2017 competition.",
  "icons": [
    {
      "src": "icons/icon-32.png",
      "sizes": "32x32",
      "type": "image/png"
    },
    // ...
    {
      "src": "icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start\_url": "/pwa-examples/js13kpwa/index.html",
  "display": "fullscreen",
  "theme\_color": "#B12A34",
  "background\_color": "#B12A34"
}
```

Названия большинства полей говорят сами за себя, но давайте разберём документ и объясним всё подробно:

* `name`: Полное название вашего приложения.
* `short_name`: Короткое название для отображения на домашнем экране.
* `description`: Одно-два предложения, описывающих приложение.
* `icons`: Куча информации о значках — URL, размеры, типы. Не забудьте указать хотя бы несколько, чтобы иконка лучше подходила под устройство пользователя
* `start_url`: Загружаемый исходный документ при запуске приложения
* `display`: Как приложение должно отображаться; может быть fullscreen (полноэкранный), standalone (автономный), minimal-ui (минимальный пользовательский интерфейс), browser (браузер)
* `theme_color`: Основной цвет для интерфейса, используемый операционной системой
* `background_color`: Цвет для фона, используемый при установке и на заставке

Минимальные требования к манифесту - `name` и хотя бы один значок (с `src`, `size` и `type`). Поля `description`, `short_name`, и `start_url` являются рекомендуемыми. Вы можете использовать даже больше полей, чем указано выше — не забудьте проверить ссылку на Web App Manifest reference.

Добавить на домашний экран
--------------------------

"Добавить на домашний экран" (кратко: a2hs) - это функция, реализованная браузерами, которая берёт информацию, найденную в веб-манифесте, и использует для добавления приложения на домашний экран устройства со значком и именем. Это работает при выполнении требований, описанных выше.

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

![Add to Home screen popup of js13kPWA.](/ru/docs/Web/Progressive_web_apps/Tutorials/js13kGames/Installable_PWAs/js13kpwa-icon.png)

После того, как пользователь кликнет на иконку, отобразится баннер установки. Информация в баннере генерируется на основе файла-манифеста — имя и значок отображаются в приглашении.

![Install banner of js13kPWA.](/ru/docs/Web/Progressive_web_apps/Tutorials/js13kGames/Installable_PWAs/js13kpwa-banner.png)

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

![Add to Home screen popup of js13kPWA.](/ru/docs/Web/Progressive_web_apps/Tutorials/js13kGames/Installable_PWAs/js13kpwa-add.png)

При подтверждении ярлык будет добавлен на рабочий стол.

![](/ru/docs/Web/Progressive_web_apps/Tutorials/js13kGames/Installable_PWAs/js13kpwa-installed.png)

После этого пользователь может запустить приложение и сразу начать его использовать. Обратите внимание, иногда у PWA (в зависимости от браузера и/или операционной системы) в правом нижнем углу отображается иконка браузера, чтобы пользователи понимали, что работают с веб-приложением.

### Экран загрузки

В некоторых браузерах, на основе информации из манифеста, создаётся заставка, отображаемая при запуске PWA

![](/ru/docs/Web/Progressive_web_apps/Tutorials/js13kGames/Installable_PWAs/js13kpwa-splash.png)

Иконка и фоновый цвет использовались для создания заставки.

Итог
----

В статье мы узнали, как сделать PWA устанавливаемыми, используя веб-манифест, и добавить их на главный экран.

Для получения большей информации, можете почитать наш Add to Home screen гайд (en-US). В настоящее время поддержка ограничена браузерами Firefox для Android 58+, Мобильным Chrome и Android Webview 31+, также Opera для Android 32+, но поддержка должна расширяться в ближайшем будущем.

Теперь давайте перейдём к последнему фрагменту PWA-головоломки — повторному запуску с помощью push-уведомлений.

* Назад  (en-US)
* Обзор: Progressive (en-US)
* Далее  (en-US)


Same-origin policy - Веб-безопасность

Same-origin policy
==================

**Политика одинакового источника** (same-origin policy) определяет как документ или скрипт, загруженный из одного источника (origin), может взаимодействовать с ресурсом из другого источника. Это помогает изолировать потенциально вредоносные документы, снижая количество возможных векторов атак.

Определение origin
------------------

Две страницы имеют одинаковый origin (источник) если протокол , порт (если указан), и хост одинаковы для обеих страниц. Время от времени, вы можете видеть это как "scheme/host/port tuple" (где "tuple" переводится как кортеж или запись набор из трёх компонент, которые вместе составляют единое целое).

В следующей таблице даны примеры origin-сравнений с URL `http://store.company.com/dir/page.html`:

| URL | Outcome | Reason |
| --- | --- | --- |
| `http://store.company.com/dir2/other.html` | Success |  |
| `http://store.company.com/dir/inner/another.html` | Success |  |
| `https://store.company.com/secure.html` | Failure | Different protocol |
| `http://store.company.com:81/dir/etc.html` | Failure | Different port |
| `http://news.company.com/dir/other.html` | Failure | Different host |

Смотрите также origin definition for `file:` URLs.

### Наследование origins

Контент из `about:blank` и `javascript:` адреса наследуют источник документа, содержащего этот URL, поскольку они не содержат информации о сервере происхождения.

**Примечание:** Например, `about:blank` часто используется в качестве URL новых, пустых окон в которые родительский скрипт записывает контент (например, с помощью `Window.open()` (en-US)). Если это окно также содержит JavaScript, то скрипт будет наследовать то же происхождение, что и его родитель.

**Предупреждение:** `data:` адреса получают новый, пустой, безопасный контекст.

### Исключения в Internet Explorer

Internet Explorer два основных исключения из политики одно происхождения:

Trust Zones (Зоны доверия)

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

Порт

IE не включает порт в same-origin проверку. Следовательно, `https://company.com:81/index.html` и `https://company.com/index.html` являются адресами одного происхождения и ограничения действовать не будут.

Эти исключения являются нестандартными и не поддерживаются в любом другом браузере

Изменение origin
----------------

Страница может изменить свой оригинальный origin с некоторыми ограничениями. Скрипт может установить значение `document.domain` на текущий домен или супердомен текущего домена. Если значение будет установлено на супердомен текущего домена, более короткий домен будет использован для последующей проверки origin'а. Например, предполагается, что скрипт в документе по адресу `http://store.company.com/dir/other.html` выполняется следующим выражением:

```js
document.domain = "company.com";
```

После этого, страница может пройти такую же проверку на `http://company.com/dir/page.html` (`предполагая, что http://company.com/dir/page.html` установил `document.domain` в значение "`company.com`" чтобы указать, что у него получилось разрешение - смотри `document.domain`). Однако, `company.com` **не может** установить `document.domain` в значение `othercompany.com`, поскольку это значение не является супердоменом `company.com`.

Номер порта проверяется браузером отдельно. Любой вызов `document.domain`, включающий `document.domain = document.domain`, заменяет номер порта, устанавливая его в значение `null`. Следовательно, **невозможно** вызов `company.com:8080` обозначить `company.com` одной лишь установкой `document.domain = "company.com"` в начале. Он должен быть установлен в обоих случаях и номер портов в этих случаях должны равняться значению `null`.

**Примечание:** Когда используется `document.domain` для разрешения поддомена для родительского доступа к нему, вы должны установить `document.domain` в *такое же значение,* как в родительском домене, так и в поддомене. Это необходимо, даже если при этом просто восстанавливается исходное значение родительского домена. Несоблюдение этого правила может привести к ошибкам разрешений.

Cross-origin network access
---------------------------

The same-origin policy controls interactions between two different origins, such as when you use `XMLHttpRequest` or an `<img>` element. These interactions are typically placed into three categories:

* Cross-origin *writes* are typically allowed. Examples are links, redirects and form submissions. Certain rarely used HTTP requests require preflight (en-US).
* Cross-origin *embedding* is typically allowed. Examples are listed below.
* Cross-origin *reads* are typically not allowed, but read access is often leaked by embedding. For example, you can read the width and height of an embedded image, the actions of an embedded script, or the availability of an embedded resource.

Here are some examples of resources which may be embedded cross-origin:

* JavaScript with `<script src="..."></script>`. Error messages for syntax errors are only available for same-origin scripts.
* CSS with `<link rel="stylesheet" href="...">`. Due to the relaxed syntax rules of CSS, cross-origin CSS requires a correct `Content-Type` header. Restrictions vary by browser: IE, Firefox, Chrome, Safari (scroll down to CVE-2010-0051) and Opera.
* Images with `<img>`. Supported image formats include PNG, JPEG, GIF, BMP, SVG, ...
* Media files with `<video>` and `<audio>`.
* Plug-ins with `<object>` (en-US), `<embed>` (en-US) and `<applet>`.
* Fonts with `@font-face` (en-US). Some browsers allow cross-origin fonts, others require same-origin fonts.
* Anything with `<frame>` (en-US) and `<iframe>` (en-US). A site can use the `X-Frame-Options` (en-US) header to prevent this form of cross-origin interaction.
### How to allow cross-origin access

Use CORS (en-US) to allow cross-origin access.

### How to block cross-origin access

* To prevent cross-origin writes, check for an unguessable token in the request, known as a Cross-Site Request Forgery (CSRF) token. You must prevent cross-origin reads of pages that know this token.
* To prevent cross-origin reads of a resource, ensure that it is not embeddable. It is often necessary to prevent embedding because embedding a resource always leaks some information about it.
* To prevent cross-origin embedding, ensure that your resource cannot be interpreted as one of the embeddable formats listed above. The browser does not respect the `Content-Type` in most cases. For example, if you point a `<script>` tag at an HTML document, the browser will try to parse the HTML as JavaScript. When your resource is not an entry point to your site, you can also use a CSRF token to prevent embedding.
Cross-origin script API access
------------------------------

JavaScript APIs such as `iframe.contentWindow` (en-US), `window.parent`, `window.open` (en-US) and `window.opener` (en-US) allow documents to directly reference each other. When the two documents do not have the same origin, these references provide very limited access to `Window` and `Location` objects, as described in the next two sections.

To communicate further between documents from different origins, use `window.postMessage`.

### Window

Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-window.

The following cross-origin access to `Window` properties is allowed:

| Methods |
| --- |
| `window.blur` |
| `window.close` |
| `window.focus` (en-US) |
| `window.postMessage` |

| Attributes |  |
| --- | --- |
| `window.closed` | Read only. |
| `window.frames` | Read only. |
| `window.length` | Read only. |
| `window.location` | Read/write. |
| `window.opener` (en-US) | Read only. |
| `window.parent` | Read only. |
| `window.self` | Read only. |
| `window.top` | Read only. |
| `window.window` (en-US) | Read only. |

Some browsers allow access to more properties than the specification allows.

### Location

Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#security-location.

The following cross-origin access to `Location` properties is allowed:

| Methods |
| --- |
| `location.replace` |

| Attributes |  |
| --- | --- |
| `URLUtils.href` | Write only. |

Some browsers allow access to more properties than the specification allows.

Cross-origin data storage access
--------------------------------

Access to data stored in the browser such as localStorage (en-US) and IndexedDB are separated by origin. Each origin gets its own separate storage, and JavaScript in one origin cannot read from or write to the storage belonging to another origin.

Cookies use a separate definition of origins. A page can set a cookie for its own domain or any parent domain, as long as the parent domain is not a public suffix. Firefox and Chrome use the Public Suffix List to determine if a domain is a public suffix. Internet Explorer uses its own internal method to determine if a domain is a public suffix. The browser will make a cookie available to the given domain including any sub-domains, no matter which protocol (HTTP/HTTPS) or port is used. When you set a cookie, you can limit its availability using the Domain, Path, Secure and Http-Only flags. When you read a cookie, you cannot see from where it was set. Even if you use only secure https connections, any cookie you see may have been set using an insecure connection.

See also
--------

* Same-origin policy for file: URIs
* Same-Origin Policy at W3C
Original Document Information
-----------------------------

* Author(s): Jesse Ruderman


How to turn off form autocompletion - Веб-безопасность

How to turn off form autocompletion
===================================

В этой статье объясняется как можно отключить автозаполнение полей на сайте.

По умолчанию браузеры запоминают информацию, которую пользователи отправляют через `<input>` поля на сайтах. Это позволяет браузеру предлагать варианты для автодополнения (то есть предлагать возможные дополнения для полей, в которые пользователь начал вводить данные) или автозаполнение (то есть предварительно заполнять определённые поля при загрузке).

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

It is important to know that if you turn off autocomplete, you are **breaking** the rule 1.3.5: Identify Input Purpose in WCAG 2.1. If you are making a website that should follow WCAG, you should use autocomplete with autofill.

Disabling autocompletion
------------------------

To disable autocompletion in forms, you can set the `autocomplete` (en-US) attribute to "off":

```html
autocomplete="off"
```

You can do this either for an entire form, or for specific input elements in a form:

```html
<form method="post" action="/form" autocomplete="off">[…]</form>
```

```html
<form method="post" action="/form">
  […]
  <div>
    <label for="cc">Credit card:</label>
    <input type="text" id="cc" name="cc" autocomplete="off" />
  </div>
</form>
```

Setting `autocomplete="off"` on fields has two effects:

* It tells the browser not to save data inputted by the user for later autocompletion on similar forms, though heuristics for complying vary by browser.
* It stops the browser from caching form data in the session history. When form data is cached in session history, the information filled in by the user is shown in the case where the user has submitted the form and clicked the Back button to go back to the original form page.

If a browser keeps on making suggestions even after setting autocomplete to off, then you have to change the name attribute of the input element.

The autocomplete attribute and login fields
-------------------------------------------

Modern browsers implement integrated password management: when the user enters a username and password for a site, the browser offers to remember it for the user. When the user visits the site again, the browser autofills the login fields with the stored values.

Additionally, the browser enables the user to choose a master password that the browser will use to encrypt stored login details.

Even without a master password, in-browser password management is generally seen as a net gain for security. Since users do not have to remember passwords that the browser stores for them, they are able to choose stronger passwords than they would otherwise.

For this reason, many modern browsers do not support `autocomplete="off"` for login fields:

* If a site sets `autocomplete="off"` for a `<form>`, and the form includes username and password input fields, then the browser still offers to remember this login, and if the user agrees, the browser will autofill those fields the next time the user visits the page.
* If a site sets `autocomplete="off"` for username and password `<input>` fields, then the browser still offers to remember this login, and if the user agrees, the browser will autofill those fields the next time the user visits the page.

This is the behavior in Firefox (since version 38), Google Chrome (since 34), and Internet Explorer (since version 11).

### Preventing autofilling with autocomplete="new-password"

If you are defining a user management page where a user can specify a new password for another person, and therefore you want to prevent autofilling of password fields, you can use `autocomplete="new-password"`.

This is a hint, which browsers are not required to comply with. However modern browsers have stopped autofilling `<input>` elements with `autocomplete="new-password"` for this very reason. For example, Firefox version 67 (see Firefox bug 1119063) stopped autofilling in this case; however, Firefox 70 (see Firefox bug 1565407) can suggest securely-generated passwords, but does not autofill a saved password. See the `autocomplete` compat table (en-US) for more details.

Tools for disabling autocompletion
----------------------------------

The jquery.disableAutoFill plugin randomizes an input's `name` attribute by default. When the form is submitted, the plugin restores the original name. This prevents auto-completion for all browsers (includes third-party auto-completion extensions) but doesn't necessarily help with login fields.


Блочный контекст форматирования - Руководства Web-разработчика

Блочный контекст форматирования
===============================

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

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

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

* корневой элемент документа (`<html>`).
* плавающие элементы (элементы, у которых `float` не равно `none`)
* абсолютно позиционированные элементы (элементы, значение `position` которых либо `absolute`, либо `fixed`)
* «строчные блоки» (элементы с `display``: inline-block`)
* ячейки таблицы (элементы с `display``: table-cell`, являющимся значением по умолчанию для ячеек таблицы в HTML)
* заголовки таблицы (элементы с `display``: table-caption`, являющимся значением по умолчанию для заголовков таблицы в HTML)
* анонимные ячейки таблицы, неявно создаваемые элементами с `display``: table`, `table-row`, `table-row-group`, `table-header-group`, `table-footer-group` (значения по умолчанию для таблиц, строк таблиц, «шапок», «подвалов» и тел таблиц в HTML соответственно) либо `inline-table`
* элементы, у которых значение свойства `overflow` отличается от `visible`
* `display``: flow-root`
* элементы с `contain` (en-US)`: layout`, `content` или `strict`
* флекс-элементы (непосредственные потомки элемента с `display``: flex` или `inline-flex`)
* грид-элементы (непосредственные потомки элемента с `display``: grid` или `inline-grid`)
* многоколоночные контейнеры (элементы, у которых `column-count` или `column-width` (en-US) не равно `auto`, включая элементы с `column-count: 1`)
* `column-span` (en-US)`: all` должно всегда создавать новый блочный контекст форматирования, даже если элемент с `column-span: all` не находится в многоколоночном контейнере (изменение в спецификации, баг Chrome).

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

Блочные контексты форматирования важны для размещения плавающих элементов (см. `float`) и отмены их обтекания (см.`clear`) . Правила размещения плавающих элементов и сброса обтекания применяются только к элементам внутри одного и того же блочного контекста форматирования. Плавающие элементы не влияют на размещение содержимого внутри других блочных контекстов форматирования, и отмена обтекания распространяется только на плавающие элементы из того же самого контекста форматирования. Схлопывание внешних отступов тоже происходит только между блоками из одного и того же блочного контекста форматирования.

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

### Как сделать плавающему контенту и соседнему с ним контенту одинаковую высоту

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

В примере ниже мы имеем плавающий элемент внутри `<div>` с заданным `border`. Содержимое этого `<div>` обтекает плавающий элемент. Так как содержимое `float` выше, чем остальное содержимое, обтекающее его, `border` элемента `div` теперь проходит сквозь `float`. Как объясняется в руководстве In Flow and Out of Flow (en-US), плавающий элемент был исключён из потока элементов, так что фон и граница `div` включает только его содержимое, но не элемент `float`.

### Использование `overflow: auto;`

Создадим новый блочный контекст форматирования, который будет содержать в себе плавающий элемент. Раньше обычным способом сделать это было установить `overflow: auto` или другое значение, отличное от значения по умолчанию `overflow: visible`.

Задание `overflow: auto` создало новый блочный контекст форматирования, включающий `float`. Теперь `div` стал мини-слоем внутри нашего слоя. Любые дочерние элементы войдут в него.

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

### Использование `display: flow-root`

Одно из новых значений свойства `display` позволяет нам создавать новый блочный контекст форматирования без всяких потенциально проблемных побочных эффектов. Использование `display: flow-root` как свойство содержащего блока, создаёт новый блочный контекст форматирования.

#### CSS
```

<div class="box">
  <div class="float">I am a floated box!</div>
  <p>I am content inside the container.</p>
</div>
```

```css
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
  display: flow-root;
}
.float {
  float: left;
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
}
```

С помощью `display: flow-root;` применённом на элементе `<div>`, всё внутри этого контейнера будет участвовать в едином блочном контексте форматирования этого контейнера, и плавающие элементы не будут торчать из нижней части контейнера.

Задание значения `flow-root` имеет смысл тогда, когда вы понимаете, что вы создаёте что-то, что будет действовать так же, как действует корневой `root` элемент (`<html>` в браузерах) в том плане, что он создаёт новый контекст для компоновки потока внутри него.

**Примечание:** `display: flow-root;` не поддерживается в Safari.

### Схлопывание границ margin

Создание нового блочного контекста форматирования предотвращает эффект схлопывания границ между двумя соседними div:

#### HTML

```html
<div class="blue"></div>
<div class="red-outer">
  <div class="red-inner">red inner</div>
</div>
```

#### CSS

```css
.blue,
.red-inner {
  height: 50px;
  margin: 10px 0;
}

.blue {
  background: blue;
}

.red-outer {
  overflow: hidden;
  background: red;
}
```

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

* CSS 2.1
* CSS Display Level 3
Статьи по теме
--------------

* `float`, `clear`
* Ключевые концепции CSS
    + Синтаксис CSS
    + @-правила
    + комментарии
    + специфичность
    + наследование
    + блочная модель
    + режимы компоновки
    + модели визуального форматирования
    + Схлопывание отступов
    + Значения
        - начальные
        - вычисленные
        - используемые
        - действительные
    + Синтаксис определения значений (en-US)
    + Сокращённые свойства
    + Замещаемые элементы


related_applications - Web App Manifest

related\_applications
=====================

|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Example |
```json
"related\_applications": [
  {
    "platform": "play",
    "url": "https://play.google.com/store/apps/details?id=com.example.app1",
    "id": "com.example.app1"
  }
]
```
 |

Поле `related_applications` field is an array of objects specifying native applications that are installable by, or accessible to, the underlying platform — for example, a native Android application obtainable through the Google Play Store. Предполагается, что такие приложения являются альтернативами веб-сайту манифеста, который предоставляет аналогичные/эквивалентные функции - как эквивалент нативного приложения.

**Примечание:** Разработчик может указать, что нативные приложения предпочтительнее, чем веб-приложение, установив значение `prefer_related_applications` в `true`.

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

```json
"related\_applications": [
  {
    "platform": "play",
    "url": "https://play.google.com/store/apps/details?id=com.example.app1",
    "id": "com.example.app1"
  }, {
    "platform": "itunes",
    "url": "https://itunes.apple.com/app/example-app1/id123456789"
  }
]
```

Значения
--------

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

| Свойство | Описание |
| --- | --- |
| `platform` | Платформа, на которой может быть найдено приложение. List of available values |
| `url` | URL, по которому может быть найдено приложение. |
| `id` | ID, используемое для представления приложения на определённой платформе. |

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

| Specification |
| --- |
| Web Application Manifest # related\_applications-member |

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

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


background_color - Web App Manifest

background\_color
=================

|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Example |
```json
"background\_color": "red"
```
 |

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

Therefore `background_color` should match the `background-color` CSS property in the site's stylesheet for a smooth transition between launching the web application and loading the site's content.

**Примечание:** Свойство `background_color` предназначено только для улучшения удобства пользования, пока главная таблица стилей загружается из сети или с носителя; не должно быть использовано агентом пользователя как свойство CSS `background-color`, когда стили приложения станут доступны.

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

```json
"background\_color": "red"
```

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

| Specification |
| --- |
| Web Application Manifest # background\_color-member |

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

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


description - Web App Manifest

description
===========

|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Example |
```json
"description": "Удивительное приложение, которое поможет вам достичь вашей мечты."
```
 |

`description` это строка, в которой разработчики могут объяснить, что делает приложение. `description` способно к направленности, что означает, что оно может отображаться слева направо или справа налево на основе значений свойств `dir` и `lang` манифеста.

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

Простой `description` на языке слева направо:

```json
"description": "Удивительное приложение, которое поможет вам достичь вашей мечты."
```

`description` на арабском языке, который будет отображаться справа налево:

```json
"dir": "rtl",
"lang": "ar",
"description": ".تطبيق رائع سيساعدك على تحقيق أحلامك"
```

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

| Specification |
| --- |
| Web App Manifest - Application Information # description-member |

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

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


icons - Web App Manifest

icons
=====

|  |  |
| --- | --- |
| Type | `Array` |
| Mandatory | Yes |
| Example |
```json
"icons": [
  {
    "src": "icon.webp",
    "sizes": "48x48",
    "type": "image/webp"
  }
]
```
 |

`icons` Определяет массив объектов изображений, которые могут использованы как иконки приложения в различных контекстах. К примеру, они могут быть использованы для представления приложения среди списка других приложений или для интеграции его с переключателем задач ОС и/или настроек системы.

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

```json
"icons": [
  {
    "src": "icon/lowres.webp",
    "sizes": "48x48",
    "type": "image/webp"
  },
  {
    "src": "icon/lowres",
    "sizes": "48x48"
  },
  {
    "src": "icon/hd\_hi.ico",
    "sizes": "72x72 96x96 128x128 256x256"
  },
  {
    "src": "icon/hd\_hi.svg",
    "sizes": "72x72"
  }
]
```

Значения
--------

Объекты изображений могут содержать следующие значения:

| Параметр | Описание |
| --- | --- |
| `sizes` | Строка, содержащая разделённые пробелами размеры изображения. |
| `src` |
 Путь к файлу изображения. Если `src` является относительным
 URL, основным URL будет URL манифеста.
  |
| `type` |
 Служит для определения медиа-типа изображения.Цель свойства позволить
 агенту пользователя быстро проигнорировать изображения медиа-типа,
 который он не поддерживает.
  |
| purpose |
 Определяет назначение изображения, например, если изображение
 предназначено для каких-то особых целей в контексте ОС (т. е. для
 лучшей интеграции)

`purpose`
 может иметь одно из следующих значений:
 * `badge`: Пользовательский агент может представить этот
 значок там, где ограничения пространства и/или требования к цвету
 отличаются от таковых для значка приложения.
* `maskable`: Изображение разработано с учётом
 масок значков и безопасной зоны, так что пользовательский агент может безопасно игнорировать и
 маскировать любую часть изображения за пределами безопасной зоны.
* `any`: Пользовательский агент может отображать значок в
 любом контексте (это значение по умолчанию).
 |

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

| Specification |
| --- |
| Web Application Manifest # icons-member |

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

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


theme_color - Web App Manifest

theme\_color
============

|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Example |
```json
"theme\_color": "red"
```
 |

`theme_color` определяет цвет темы по умолчанию для приложения. Иногда влияет на то, как приложение отображается ОС (например, в переключателе задач Android цвет темы окружает приложение).

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

```json
"theme\_color": "red"
```

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

| Specification |
| --- |
| Web Application Manifest # theme\_color-member |

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

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


display - Web App Manifest

display
=======

|  |  |
| --- | --- |
| Type | `String` |
| Mandatory | No |
| Example |
```json
"display": "standalone"
```
 |

**Примечание:** Если свойство `display` не указано, по умолчанию используется `"browser"`.

`display` - это строка, которая определяет предпочитаемый разработчиком режим отображения для веб-сайта. Режим отображения изменяет количество отображаемого пользовательского интерфейса браузера и может варьироваться от `"browser"` (когда отображается полное окно браузера) до `"fullscreen"` (когда приложение полноэкранно).

**Примечание:** вы можете выборочно применить CSS к своему приложению на основе режима отображения, используя медиа-функцию `display-mode` (en-US). Это может быть использовано для обеспечения более гладкого перехода для пользователя от загрузки сайта по URL к запуску по иконке на рабочем столе.

Значения
--------

Валидные значения следующие:

| Режим отображения | Описание | Резервный режим отображения |
| --- | --- | --- |
| `fullscreen` | Используется все доступное пространство экрана и агент пользователя chrome не отображается. | `standalone` |
| `standalone` | Приложение будет выглядеть и ощущаться, как отдельное приложение. Это может включать наличие другого окна у приложения, собственной иконки в меню запуска и т.д. В этом режиме агент пользователя будет исключать элементы пользовательского интерфейса (ПИ) для контроля за навигацией, но может включать другие элементы ПИ, такие как статус-бар. | `minimal-ui` |
| `minimal-ui` | Приложение будет выглядеть и ощущаться, как отдельное приложение, но будет иметь минимальный набор элементов ПИ для контроля над навигацией. Элементы будут варьироваться в зависимости от браузера. | `browser` |
| `browser` | Приложение открывается в обычной вкладке браузера или новом окне, в зависимости от браузера и платформы. По умолчанию. | (None) |

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

```json
"display": "standalone"
```

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

| Specification |
| --- |
| Web Application Manifest # display-member |

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

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