update func

This commit is contained in:
2025-03-05 12:33:59 +03:00
parent e60ec041ae
commit 31caa0e6de
15 changed files with 539 additions and 1 deletions

View File

@@ -46,4 +46,50 @@ message = 'Hello';
```js
typeof null == "object" // ошибка в языке
typeof function(){} == "function" // именно для функций
```
## Устаревшее ключевое слово "var"
Обычно var не используется в современных скриптах, но всё ещё может скрываться в старых.\
Существует 2 основных отличия var от let/const:
- Переменные var не имеют блочной области видимости, они ограничены, как минимум, телом функции.
- Объявления (инициализация) переменных var производится в начале исполнения функции (или скрипта для глобальных переменных).
### Для «var» не существует блочной области видимости
Область видимости переменных `var` ограничивается либо функцией, либо, если переменная глобальная, то скриптом. Такие переменные доступны за пределами блока.
`var` выходит за пределы блоков `if`, `for` и подобных. Это происходит потому, что на заре развития JavaScript блоки кода не имели лексического окружения.
### «var» допускает повторное объявление
Используя var, можно переобъявлять переменную сколько угодно раз. Повторные var игнорируются.
### «var» обрабатываются в начале запуска функции
Это поведение называется «hoisting» (всплытие, поднятие), потому что все объявления переменных var «всплывают» в самый верх функции.
Объявления переменных var обрабатываются в начале выполнения функции (или запуска скрипта, если переменная является глобальной).
Другими словами, переменные var считаются объявленными с самого начала исполнения функции вне зависимости от того, в каком месте функции реально находятся их объявления (при условии, что они не находятся во вложенной функции).
***Объявления переменных «всплывают», но присваивания значений нет.***
### IIFE
В прошлом, поскольку существовал только `var`, а он не имел блочной области видимости, программисты придумали способ её эмулировать. Этот способ получил название «Immediately-invoked function expressions» (сокращенно IIFE).
Здесь создаётся и немедленно вызывается Function Expression. Так что код выполняется сразу же и у него есть свои локальные переменные.
```js
// Способы создания IIFE
(function() {
var message = "Привет";
alert(message); // Привет
})(); // Круглые скобки вокруг функции
(function() {
alert("Круглые скобки вокруг всего выражения");
}());
!function() {
alert("Выражение начинается с логического оператора НЕ");
}();
+function() {
alert("Выражение начинается с унарного плюса");
}();
```

View File

@@ -0,0 +1,77 @@
---
sidebar_position: 8
---
# Свойства - геттеры и сеттеры
## Геттеры и сеттеры
Свойства-аксессоры представлены методами: «геттер» для чтения и «сеттер» для записи. При литеральном объявлении объекта они обозначаются get и set
```js
let obj = {
get propName() {
// геттер, срабатывает при чтении obj.propName
},
set propName(value) {
// сеттер, срабатывает при записи obj.propName = value
}
};
```
## Дескрипторы свойств доступа
Дескрипторы свойств-аксессоров отличаются от «обычных» свойств-данных.
Свойства-аксессоры не имеют `value` и `writable`, но взамен предлагают функции `get` и `set`.
То есть, дескриптор аксессора может иметь:
- **get** функция без аргументов, которая сработает при чтении свойства,
- **set** функция, принимающая один аргумент, вызываемая при присвоении свойства,
- **enumerable** то же самое, что и для свойств-данных,
- **configurable** то же самое, что и для свойств-данных.
Например, для создания аксессора `fullName` при помощи `defineProperty` мы можем передать дескриптор с использованием `get` и `set`
```js
let user = {
name: "John",
surname: "Smith"
};
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
alert(user.fullName); // John Smith
for(let key in user) alert(key); // name, surname
```
## Умные геттеры/сеттеры
Геттеры/сеттеры можно использовать как обёртки над «реальными» значениями свойств, чтобы получить больше контроля над операциями с ними.
Например, если мы хотим запретить устанавливать короткое имя для `user`, мы можем использовать сеттер `name` для проверки, а само значение хранить в отдельном свойстве `_name`:
```js
let user = {
get name() {
return this._name;
},
set name(value) {
if (value.length < 4) {
alert("Имя слишком короткое, должно быть более 4 символов");
return;
}
this._name = value;
}
};
user.name = "Pete";
alert(user.name); // Pete
user.name = ""; // Имя слишком короткое...
```
## Использование для совместимости
У аксессоров есть интересная область применения они позволяют в любой момент взять «обычное» свойство и изменить его поведение, поменяв на геттер и сеттер.

View File

@@ -0,0 +1,62 @@
---
sidebar_position: 11
---
# Формат JSON
- JSON это формат данных, который имеет собственный независимый стандарт и библиотеки для большинства языков программирования.
- JSON поддерживает простые объекты, массивы, строки, числа, логические значения и null.
- JavaScript предоставляет методы JSON.stringify для сериализации в JSON и JSON.parse для чтения из JSON.
- Оба метода поддерживают функции преобразования для интеллектуального чтения/записи.
- Если объект имеет метод toJSON, то он вызывается через JSON.stringify.
JavaScript предоставляет методы:
- JSON.stringify для преобразования объектов в JSON.
- JSON.parse для преобразования JSON обратно в объект.
JSON поддерживает следующие типы данных:
- Объекты \{ ... }
- Массивы [ ... ]
- Примитивы:
- строки,
- числа,
- логические значения true/false,
- null.
## JSON.stringify
JSON.stringify пропускает некоторые специфические свойства объектов JavaScript
- Свойства-функции (методы).
- Символьные ключи и значения.
- Свойства, содержащие undefined.
💥 ***Важное ограничение: не должно быть циклических ссылок.***
## Исключаем и преобразуем: replacer
- **value** Значение для кодирования.
- **replacer** Массив свойств для кодирования или функция соответствия function(key, value).
- **space** Дополнительное пространство (отступы), используемое для форматирования.
В большинстве случаев JSON.stringify используется только с первым аргументом. Но если нам нужно настроить процесс замены, например, отфильтровать циклические ссылки, то можно использовать второй аргумент JSON.stringify.
```js
let json = JSON.stringify(value[, replacer, space])
```
## Форматирование: space
Третий аргумент в JSON.stringify(value, replacer, space) это количество пробелов, используемых для удобного форматирования.
## Пользовательский «toJSON»
Как и toString для преобразования строк, объект может предоставлять метод toJSON для преобразования в JSON. JSON.stringify автоматически вызывает его, если он есть.
## JSON.parse
Чтобы декодировать JSON-строку, нам нужен другой метод с именем JSON.parse.
```js
let value = JSON.parse(str[, reviver]);
```
- **str** JSON для преобразования в объект.
- **reviver** Необязательная функция, которая будет вызываться для каждой пары (ключ, значение) и может преобразовывать значение.
Кроме того, JSON не поддерживает комментарии.

View File

@@ -53,7 +53,7 @@ function defer(f, ms) {
}
```
#### Стрелочные функции:
## Особенности стрелочных функций:
- Не имеют this.
- Не имеют arguments.
- Не могут быть вызваны с new.

View File

@@ -0,0 +1,62 @@
---
sidebar_position: 5
---
# Остаточные параметры и оператор расширения
Когда мы видим "..." в коде, это могут быть как остаточные параметры, так и оператор расширения.
Как отличить их друг от друга:
- Если ... располагается в конце списка параметров функции, то это «остаточные параметры». Он собирает остальные неуказанные аргументы и делает из них массив.
- Если ... встретился в вызове функции или где-либо ещё, то это «оператор расширения». Он извлекает элементы из массива.
Полезно запомнить:
- Остаточные параметры используются, чтобы создавать новые функции с неопределённым числом аргументов.
- С помощью оператора расширения можно вставить массив в функцию, которая по умолчанию работает с обычным списком аргументов.
-
Вместе эти конструкции помогают легко преобразовывать наборы значений в массивы и обратно.
К аргументам функции можно обращаться и по-старому — через псевдомассив arguments.
## Остаточные параметры (...)
Остаточные параметры могут быть обозначены через три точки `....`
```js
function sumAll(...args) { // args — имя массива
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6
```
💥 ***Остаточные параметры должны располагаться в конце***
```js
function f(arg1, ...rest, arg2) { // arg2 после ...rest ?!
// Ошибка
}
```
## Переменная "arguments"
Все аргументы функции находятся в псевдомассиве `arguments` под своими порядковыми номерами.
Хотя arguments похож на массив, и его тоже можно перебирать, это всё же не массив. Методы массивов не поддерживаются.
```js
function showName() {
alert( arguments.length );
alert( arguments[0] );
alert( arguments[1] );
// for (let arg of arguments) alert(arg); // Объект arguments можно перебирать
}
showName("Юлий", "Цезарь"); // Вывод: 2, Юлий, Цезарь
showName("Илья");// Вывод: 1, Илья, undefined (второго аргумента нет)
```
💥 ***Стрелочные функции не имеют "arguments"***
Если мы обратимся к arguments из стрелочной функции, то получим аргументы внешней «нормальной» функции.
## Оператор расширения
Когда `...arr` используется при вызове функции, он «расширяет» перебираемый объект `arr` в список аргументов.
```js
let arr = [3, 5, 1];
alert( Math.max(...arr) ); // 5 (оператор "раскрывает" массив в список аргументов)
```

View File

@@ -0,0 +1,113 @@
---
sidebar_position: 6
---
# Область видимости переменных, замыкание
Источник: [https://learn.javascript.ru/closure](https://learn.javascript.ru/closure)
## Блоки кода
Если переменная объявлена внутри блока кода `{...}`, то она видна только внутри этого блока.
С помощью блоков `{...}` мы можем изолировать часть кода, выполняющую свою собственную задачу, с переменными, принадлежащими только ей
Для `if`, `for`, `while` и т.д. переменные, объявленные в блоке кода `{...}`, также видны только внутри
## Вложенные функции
Функция называется «вложенной», когда она создаётся внутри другой функции.
Она может получить доступ к внешним переменным.
Вложенная функция может быть возвращена: либо в качестве свойства нового объекта (если внешняя функция создаёт объект с методами), либо сама по себе. И затем может быть использована в любом месте. Не важно где, она всё так же будет иметь доступ к тем же внешним переменным.
## Лексическое окружение
#### Переменные
В JavaScript у каждой выполняемой функции, блока кода `{...}` и скрипта есть связанный с ними внутренний (скрытый) объект, называемый ***лексическим окружением** `LexicalEnvironment`.
Объект лексического окружения состоит из двух частей:
1. **Environment Record** объект, в котором как свойства хранятся все локальные переменные (а также некоторая другая информация, такая как значение this).
2. Ссылка на **внешнее лексическое окружение** то есть то, которое соответствует коду снаружи (снаружи от текущих фигурных скобок).
**«Переменная» это просто свойство специального внутреннего объекта: `Environment Record`.** \
**«Получить или изменить переменную», означает, «получить или изменить свойство этого объекта».**
- Переменная это свойство специального внутреннего объекта, связанного с текущим выполняющимся блоком/функцией/скриптом.
- Работа с переменными это на самом деле работа со свойствами этого объекта.
#### Function Declaration
**Разница заключается в том, что Function Declaration мгновенно инициализируется полностью.**
Когда создается лексическое окружение, Function Declaration сразу же становится функцией, готовой к использованию (в отличие от `let`, который до момента объявления не может быть использован).
Поэтому мы можем вызвать функцию, объявленную как Function Declaration, до самого её объявления.
Такое поведение касается только Function Declaration, а не Function Expression, в которых мы присваиваем функцию переменной.
#### Внутреннее и внешнее лексическое окружение
Когда запускается функция, в начале ее вызова автоматически создается новое лексическое окружение для хранения локальных переменных и параметров вызова.
![](images/06-closure-1.png)
В процессе вызова функции у нас есть два лексических окружения: внутреннее (для вызываемой функции) и внешнее (глобальное):
- Внутреннее лексическое окружение соответствует текущему выполнению say.\
В нём находится одна переменная name, параметр функции. Мы вызываем say("John"), так что значение переменной name равно "John".
- Внешнее лексическое окружение это глобальное лексическое окружение.\
В нём находятся переменная phrase и сама функция.
У внутреннего лексического окружения есть ссылка на внешнее `outer`.
**Когда код хочет получить доступ к переменной сначала происходит поиск во внутреннем лексическом окружении, затем во внешнем, затем в следующем и так далее, до глобального.**
Если переменная не была найдена, это будет ошибкой в строгом режиме (`use strict`). Без строгого режима, для обратной совместимости, присваивание несуществующей переменной создаёт новую глобальную переменную с таким же именем.
#### Возврат функции
```js
function makeCounter() {
let count = 0;
return function() {
return count++;
};
}
let counter = makeCounter();
```
В начале каждого вызова makeCounter() создается новый объект лексического окружения, в котором хранятся переменные для конкретного запуска makeCounter.
Таким образом, мы имеем два вложенных лексических окружения, как в примере выше:
![](images/06-closure-2.png)
Отличие заключается в том, что во время выполнения makeCounter() создается крошечная вложенная функция, состоящая всего из одной строки: return count++. Мы ее еще не запускаем, а только создаем.
Все функции помнят лексическое окружение, в котором они были созданы. Технически здесь нет никакой магии: все функции имеют скрытое свойство [[Environment]], которое хранит ссылку на лексическое окружение, в котором была создана функция:
![](images/06-closure-3.png)
Таким образом, counter.[[Environment]] имеет ссылку на \{count: 0} лексического окружения. Так функция запоминает, где она была создана, независимо от того, где она вызывается. Ссылка на [[Environment]] устанавливается один раз и навсегда при создании функции.
Впоследствии, при вызове counter(), для этого вызова создается новое лексическое окружение, а его внешняя ссылка на лексическое окружение берется из counter.[[Environment]]:
![](images/06-closure-4.png)
Теперь, когда код внутри counter() ищет переменную count, он сначала ищет ее в собственном лексическом окружении (пустом, так как там нет локальных переменных), а затем в лексическом окружении внешнего вызова makeCounter(), где находит count и изменяет ее.
***Переменная обновляется в том лексическом окружении, в котором она существует.***
![](images/06-closure-5.png)
Если мы вызовем counter() несколько раз, то в одном и том же месте переменная count будет увеличена до 2, 3 и т.д.
💥 **Замыкания**
**Замыкание** это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В некоторых языках это невозможно, или функция должна быть написана специальным образом, чтобы получилось замыкание. Но, как было описано выше, в JavaScript, все функции изначально являются замыканиями.
То есть они автоматически запоминают, где были созданы, с помощью скрытого свойства `[[Environment]]`, и все они могут получить доступ к внешним переменным.
Когда на собеседовании фронтенд-разработчику задают вопрос: «что такое замыкание?», правильным ответом будет определение замыкания и объяснения того факта, что все функции в JavaScript являются замыканиями, и, может быть, несколько слов о технических деталях: свойстве `[[Environment]]` и о том, как работает лексическое окружение.
Есть только одно исключение, когда функция создаётся с использованием `new Function`, в её `[[Environment]]` записывается ссылка не на внешнее лексическое окружение, в котором она была создана, а на глобальное. Поэтому такая функция имеет доступ только к глобальным переменным.
## Сборка мусора
Обычно лексическое окружение удаляется из памяти вместе со всеми переменными после завершения вызова функции. Это связано с тем, что на него нет ссылок. Как и любой объект JavaScript, оно хранится в памяти только до тех пор, пока к нему можно обратиться.
Однако если существует вложенная функция, которая все еще доступна после завершения функции, то она имеет свойство `[[Environment]]`, ссылающееся на лексическое окружение.
В этом случае лексическое окружение остается доступным даже после завершения работы функции.
Объект лексического окружения исчезает, когда становится недоступным (как и любой другой объект). Другими словами, он существует только до тех пор, пока на него ссылается хотя бы одна вложенная функция.
#### Оптимизация на практике
Но на практике движки JavaScript пытаются это оптимизировать. Они анализируют использование переменных и, если легко по коду понять, что внешняя переменная не используется она удаляется.
***Одним из важных побочных эффектов в V8 (Chrome, Edge, Opera) является то, что такая переменная становится недоступной при отладке.***

View File

@@ -0,0 +1,20 @@
---
sidebar_position: 7
---
# Глобальный объект
Глобальный объект предоставляет переменные и функции, доступные в любом месте программы. По умолчанию это те, что встроены в язык или среду исполнения.
В браузере он называется `window`, в Node.js — `global`, в другой среде исполнения может называться иначе.
Недавно `globalThis` был добавлен в язык как стандартизированное имя для глобального объекта, которое должно поддерживаться в любом окружении.
В браузере глобальные функции и переменные, объявленные с помощью `var` (не `let/const`!), становятся свойствами глобального объекта:
- Глобальный объект хранит переменные, которые должны быть доступны в любом месте программы.
- Это включает в себя как встроенные объекты, например, Array, так и характерные для окружения свойства, например, window.innerHeight высота окна браузера.
- Глобальный объект имеет универсальное имя globalThis.
- …Но чаще на него ссылаются по-старому, используя имя, характерное для данного окружения, такое как window (браузер) и global (Node.js).
- Следует хранить значения в глобальном объекте, только если они действительно глобальны для нашего проекта. И стараться свести их количество к минимуму.
- В браузерах, если только мы не используем модули, глобальные функции и переменные, объявленные с помощью var, становятся свойствами глобального объекта.
- Для того, чтобы код был проще и в будущем его легче было поддерживать, следует обращаться к свойствам глобального объекта напрямую, как window.x.

View File

@@ -0,0 +1,69 @@
---
sidebar_position: 8
---
# Планирование: setTimeout и setInterval
- Методы `setInterval(func, delay, ...args)` и `setTimeout(func, delay, ...args)` позволяют выполнять func регулярно или только один раз после задержки `delay`, заданной в мс.
- Для отмены выполнения необходимо вызвать `clearInterval/clearTimeout` со значением, которое возвращают методы `setInterval/setTimeout`.
- Вложенный вызов `setTimeout` является более гибкой альтернативой `setInterval`. Также он позволяет более точно задать интервал между выполнениями.
- Планирование с нулевой задержкой `setTimeout(func,0)` или, что то же самое, `setTimeout(func)` используется для вызовов, которые должны быть исполнены как можно скорее, после завершения исполнения текущего кода.
- Браузер ограничивает 4-мя мс минимальную задержку между пятью и более вложенными вызовами `setTimeout`, а также для `setInterval`, начиная с 5-го вызова.
Методы планирования не гарантируют точную задержку. Например, таймер в браузере может замедляться по многим причинам:
- Перегружен процессор.
- Вкладка браузера в фоновом режиме.
- Работа ноутбука от аккумулятора.
Всё это может увеличивать минимальный интервал срабатывания таймера (и минимальную задержку) до 300 или даже 1000 мс в зависимости от браузера и настроек производительности ОС.
## setTimeout
setTimeout позволяет вызвать функцию один раз через определённый интервал времени.
```js
let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...);
```
💥 Передавайте функцию, но не запускайте её
Разработчики иногда ошибаются, добавляя скобки () после функции. Это не работает, потому что `setTimeout` ожидает ссылку на функцию.
Вызов `setTimeout` возвращает «идентификатор таймера» `timerId`, который можно использовать для отмены дальнейшего выполнения.
```js
let timerId = setTimeout(...);
clearTimeout(timerId);
```
## setInterval
`setInterval` позволяет вызывать функцию регулярно, повторяя вызов через определённый интервал времени.
Метод `setInterval` имеет такой же синтаксис как `setTimeout`
```js
let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...);
```
Чтобы остановить дальнейшее выполнение функции, необходимо вызвать clearInterval(timerId).
## Вложенный setTimeout
Есть два способа запускать что-то регулярно. Один из них `setInterval`. Другим является вложенный `setTimeout`.
Вложенный `setTimeout` более гибкий метод, чем `setInterval`. С его помощью последующий вызов может быть задан по-разному в зависимости от результатов предыдущего.
Например, необходимо написать сервис, который отправляет запрос для получения данных на сервер каждые 5 секунд, но если сервер перегружен, то необходимо увеличить интервал запросов до 10, 20, 40 секунд… Вот псевдокод:
```js
let delay = 5000;
let timerId = setTimeout(function request() {
...отправить запрос...
if (ошибка запроса из-за перегрузки сервера) {
// увеличить интервал для следующего запроса
delay *= 2;
}
timerId = setTimeout(request, delay);
}, delay);
```
***Вложенный `setTimeout` позволяет задать задержку между выполнениями более точно, чем `setInterval`.***
## setTimeout с нулевой задержкой
Особый вариант использования: `setTimeout(func, 0)` или просто `setTimeout(func)`.
Это планирует вызов `func` настолько быстро, насколько это возможно. Но планировщик будет вызывать функцию только после завершения выполнения текущего кода.
Так вызов функции будет запланирован сразу после выполнения текущего кода.

View File

@@ -0,0 +1,25 @@
---
sidebar_position: 9
---
# Декораторы и переадресация вызова, call/apply
Источник [https://learn.javascript.ru/call-apply-decorators](https://learn.javascript.ru/call-apply-decorators)
Декоратор это обёртка вокруг функции, которая изменяет поведение последней. Основная работа по-прежнему выполняется функцией.
Обычно безопасно заменить функцию или метод декорированным, за исключением одной мелочи. Если исходная функция предоставляет свойства, такие как `func.calledCount` или типа того, то декорированная функция их не предоставит. Потому что это обёртка. Так что нужно быть осторожным в их использовании. Некоторые декораторы предоставляют свои собственные свойства.
Декораторы можно рассматривать как «дополнительные возможности» или «аспекты», которые можно добавить в функцию. Мы можем добавить один или несколько декораторов. И всё это без изменения кода оригинальной функции!
Для реализации `cachingDecorator` мы используем методы:
- `func.call(context, arg1, arg2…)` вызывает `func` с данным контекстом и аргументами.
- `func.apply(context, args)` вызывает `func`, передавая `context` как `this` и псевдомассив `args` как список аргументов.
В основном переадресация вызова выполняется с помощью apply:
```js
let wrapper = function(original, arguments) {
return original.apply(this, arguments);
};
```
Весьма распространено заимствовать методы массива и применять их к arguments. В качестве альтернативы можно использовать объект с остаточными параметрами ...args, который является реальным массивом.

View File

@@ -0,0 +1,64 @@
---
sidebar_position: 10
---
# Привязка контекста к функции
Источник: [https://learn.javascript.ru/bind](https://learn.javascript.ru/bind)
При передаче методов объекта в качестве колбэков, например для setTimeout, возникает известная проблема потеря this.
Метод `bind` возвращает «привязанный вариант» функции `func`, фиксируя контекст `this` и первые аргументы `arg1`, `arg2…`, если они заданы.
Обычно `bind` применяется для фиксации `this` в методе объекта, чтобы передать его в качестве колбэка. Например, для `setTimeout`.
Когда мы привязываем аргументы, такая функция называется «частично применённой» или «частичной».
Частичное применение удобно, когда мы не хотим повторять один и тот же аргумент много раз. Например, если у нас есть функция send(from, to) и from всё время будет одинаков для нашей задачи, то мы можем создать частично применённую функцию и дальше работать с ней.
## Потеря «this»
Мы уже видели примеры потери `this`. Как только метод передаётся отдельно от объекта `this` теряется.
```js
let user = {
firstName: "Вася",
sayHi() {
alert(`Привет, ${this.firstName}!`);
}
};
setTimeout(user.sayHi, 1000); // Привет, undefined!
```
Это произошло потому, что setTimeout получил функцию sayHi отдельно от объекта user (именно здесь функция и потеряла контекст).
> Метод setTimeout в браузере имеет особенность: он устанавливает this=window для вызова функции (в Node.js this становится объектом таймера, но здесь это не имеет значения). Таким образом, для this.firstName он пытается получить window.firstName, которого не существует. В других подобных случаях this обычно просто становится undefined.
## Решение 1: сделать функцию-обёртку
Самый простой вариант решения это обернуть вызов в анонимную функцию, создав замыкание:
```js
let user = {
firstName: "Вася",
sayHi() {
alert(`Привет, ${this.firstName}!`);
}
};
setTimeout(function() {
user.sayHi(); // Привет, Вася!
}, 1000);
```
## Решение 2: привязать контекст с помощью bind
Результатом вызова `func.bind(context)` является особый «экзотический объект» (термин взят из спецификации), который вызывается как функция и прозрачно передаёт вызов в `func`, при этом устанавливая `this=context`.
Другими словами, вызов boundFunc подобен вызову `func` с фиксированным `this`.
```js
let user = {
firstName: "Вася",
sayHi() {
alert(`Привет, ${this.firstName}!`);
}
};
let sayHi = user.sayHi.bind(user); // (*)
sayHi(); // Привет, Вася!
setTimeout(sayHi, 1000); // Привет, Вася!
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB