Продвинутая работа с функциями Flashcards

1
Q

Что такое рекурсия?

A

Рекурсия — это вызов функцией самой себя.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Как работает функция возведения в степень с помощью рекурсии?

A

Функция проверяет, если n равно 1, то возвращает x, иначе умножает x на результат вызова этой же функции с аргументами x и n-1.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Как работает функция возведения в степень с помощью цикла?

A

Функция использует цикл, чтобы умножить x на самого себя n раз, после чего возвращает результат.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Почему рекурсивные задачи обычно короче, чем итеративные?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Что такое глубина рекурсии?

A

Глубина рекурсии - это общее количество вложенных вызовов (включая первый).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Что такое стек контекстов выполнения?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Что происходит, когда функция производит вложенный вызов?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Что такое связанный список?

A

Связанный список - это рекурсивная структура данных, состоящая из узлов, каждый из которых содержит значение и указатель на следующий узел.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Какая основная разница между массивом и связанным списком?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Что такое HEAD и TAIL в связанном списке?

A

HEAD — это начало связанного списка, а TAIL - это его конец.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Как добавить новый элемент в начало связанного списка?

A

Нужно создать новый элемент со значением и указателем на предыдущий HEAD, а затем переопределить HEAD, чтобы он указывал на новый элемент.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Как удалить элемент из середины связанного списка?

A

Нужно перенаправить указатель “next” удаляемого узла к следующему элементу в списке.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Какие типы связанных списков существуют?

A

Существуют односвязный список, двусвязный список и кольцевой связанный список.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

В чем отличие двусвязного списка от односвязного списка?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Как осуществляется добавление элемента в двусвязный список?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Как осуществляется удаление элемента из двусвязного списка?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Что происходит, если в функцию передать больше параметров, чем она принимает?

A

Лишние параметры не вызовут ошибки.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Что делает rest-оператор в функции?

A

Rest-оператор собирает все оставшиеся параметры функции и помещает их в массив.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Где должен располагаться rest-оператор в функции?

A

Rest-оператор должен всегда располагаться в конце.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Что такое переменная arguments?

A

Переменная arguments - это псевдомассив, в котором хранятся все аргументы, переданные в функцию.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Можно ли передать только часть аргументов в переменную arguments?

A

Нет, переменная arguments содержит все аргументы, переданные в функцию.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Можно ли использовать объект arguments в стрелочных функциях?

A

Нет, стрелочные функции не имеют переменной arguments.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Что делает spread-оператор?

A

Spread-оператор “раскрывает” итерируемый объект.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Что произойдет при использовании spread-оператора с массивом при вызове функции Math.max()?

A

Spread-оператор “раскроет” массив в список аргументов функции Math.max().

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Можно ли комбинировать spread-оператор с обычными значениями?

A

Да, можно комбинировать spread-оператор с обычными значениями.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Для чего можно использовать Array.from?

A

Array.from можно использовать, если необходимо “раскрыть” и итерируемый объект и псевдомассив.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Что такое замыкание в JavaScript?

A

Замыкание - это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В JavaScript все функции являются замыканиями, кроме случая, когда функция создается с использованием new Function.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

Что такое лексическое окружение в JavaScript?

A

Лексическое окружение - это внутренний (скрытый) объект, который есть у каждой выполняемой функции, блока кода и скрипта. Объект лексического окружения состоит из двух частей: Environment Record - объект, в котором хранятся все локальные переменные, и ссылка на внешнее лексическое окружение - на код, который снаружи текущих фигурных скобок.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Что такое Environment Record в лексическом окружении?

A

Environment Record — это объект, в котором хранятся все локальные переменные (а также некоторая другая информация, такая как this). Переменная — это свойство объекта лексического окружения, где ключ - название переменной.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

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

A

С помощью скрытого свойства [[Environment]] – ссылки, которая указывает на текущее лексическое окружение.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

Какие две части составляют объект лексического окружения в JavaScript?

A

Объект лексического окружения состоит из двух частей: Environment Record и ссылки на внешнее лексическое окружение.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

Что означает глобальное лексическое окружение в JavaScript?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

Какое состояние имеет лексическое окружение в начале скрипта?

A

Пустое.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

Что происходит при объявлении переменной в лексическом окружении?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
35
Q

Какое значение получает переменная в лексическом окружении при объявлении без присваивания?

A

undefined.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
36
Q

Что происходит с лексическим окружением при присваивании значения переменной?

A

Значение переменной обновляется в лексическом окружении.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
37
Q

Что на самом деле представляют переменные в JavaScript?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
38
Q

Как работает поиск переменных в лексическом окружении функции?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
39
Q

Какое значение получает функция при доступе к переменной?

A

Функция получает текущее значение переменной, то есть последнее значение.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
40
Q

Что происходит при создании функции Function Declaration?

A

Название функции Function Declaration инициализируется в лексическом окружении при создании лексического окружения, а не тогда, когда выполнение доходит до нее. Поэтому можно вызвать Function Declaration до того, как она объявлена.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
41
Q

Какие возможности есть для вложенных функций в JavaScript?

A

Вложенная функция может быть свойством объекта (методом функции-конструктора) или возвращаться как значением в другой функции.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
42
Q

Что происходит при вызове функции в JavaScript?

A

При каждом вызове функции создается новое лексическое окружение.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
43
Q

Можно ли получить доступ к внешней переменной из вложенной функции?

A

Да, вложенная функция может получить доступ к переменным во внешнем лексическом окружении.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
44
Q

Можно ли получить доступ к внутренним переменным из внешнего лексического окружения?

A

Нет, внешнее лексическое окружение не имеет ссылок на внутренние переменные вложенных функций.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
45
Q

Что происходит с лексическим окружением при выполнении блока if?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
46
Q

Какие переменные принадлежат лексическому окружению блока for?

A

Если переменная объявлена внутри скобок блока for с использованием let, то эта переменная принадлежит его лексическому окружению.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
47
Q

Как можно использовать блоки кода для изоляции переменных в локальной области видимости?

A

Можно использовать блоки кода { … } для изоляции переменных в локальной области видимости, чтобы избежать конфликтов с другими скриптами. В таком блоке переменные, объявленные с помощью let или const, будут видны только внутри блока, а снаружи его - не будут.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
48
Q

Что такое IIFE?

A

IIFE — это сокращение от immediately-invoked function expression, что означает моментально вызываемое функциональное выражение.
В данный момент в IIFE нет необходимости, так как современные версии JS поддерживают лексическое окружение на уровне блоков кода с помощью ключевых слов “let” и “const”.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
49
Q

Зачем программисты придумали IIFE?

A

IIFE было придумано для того, чтобы функцию можно было создать и сразу вызвать “на месте”. Раньше в JavaScript не было лексического окружения на уровне блоков кода, поэтому IIFE позволял создавать локальную область видимости и избежать конфликтов имен.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
50
Q

Как создать IIFE?

A

Для создания IIFE нужно создать Function Expression и сразу вызвать ее. Function Expression оборачивается в скобки, чтобы JavaScript не принимал его за Function Declaration. Есть несколько способов создания IIFE, например, обернуть функцию в круглые скобки, перед функцией поставить оператор ! или +, либо использовать функциональное выражение с вызовом в конце, заключенное в круглые скобки.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
51
Q

Что происходит с лексическим окружением функции после её выполнения?

A

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
52
Q

Когда объект лексического окружения умирает?

A

Объект лексического окружения умирает, когда становится недоступным, т.е. когда на него не ссылается ни одна функция.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
53
Q

Какие движки JS пытаются оптимизировать сохранение внешних переменных при жизни функции?

A

V8 (Chromium).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
54
Q

Что происходит с внешней переменной, если движок JS анализирует использование переменных и находит, что она не используется?

A

Она удаляется.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
55
Q

Какие побочные эффекты возникают при использовании отладчика в V8?

A

Переменные, которые были удалены при оптимизации, становятся недоступными при отладке.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
56
Q

Может ли внешняя переменная сохраниться при оптимизации движком JS, даже если она не используется в коде?

A

Да, если по коду не ясно, что она не используется.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
57
Q

Какое ключевое слово в JavaScript является устаревшим способом объявления переменных?

A

Ключевое слово “var”.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
58
Q

Чем ограничивается область видимости переменных, объявленных с помощью “var”?

A

Только функцией или скриптом (глобальной областью видимости).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
59
Q

Какой тип области видимости был у блоков на заре развития JavaScript?

A

На заре развития JavaScript блоки не имели лексической области видимости.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
60
Q

Можно ли достать переменную, объявленную с помощью “var”, из блока if или цикла for?

A

Да, переменную, объявленную с помощью “var”, можно достать из блока if или цикла for, так как она имеет глобальную область видимости.

61
Q

Можно ли достать переменную, объявленную с помощью “var”, из функции?

A

Достать переменную, объявленную с помощью “var”, из функции нельзя, так как ее область видимости ограничивается функцией.

62
Q

Что происходит при объявлении переменных с помощью var?

A

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

63
Q

Можно ли повторно объявить переменную с помощью let?

A

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

64
Q

Можно ли повторно объявлять переменные с помощью var?

A

Да, переменные, объявленные с помощью var, можно переобъявлять бесконечно.

65
Q

Как влияет отсутствие значения при объявлении переменной с помощью var?

A

Если переменная объявлена с помощью var без значения, то JavaScript проигнорирует это и не будет выдавать ошибку.

66
Q

Что такое всплытие (hoisting) в контексте переменных var?

A

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

67
Q

Что происходит с объявлениями переменных var при всплытии?

A

Объявления переменных var “всплывают” в начало функции, что означает, что они считаются объявленными с самого начала выполнения функции, независимо от того, где находятся их объявления в функции.

68
Q

Происходит ли всплытие у присваиваний значений переменных var?

A

Нет, всплытие не происходит у присваиваний значений переменных var. Объявления переменных “всплывают”, но присваивания значений – нет.

69
Q

Что такое свойства функции в JavaScript?

A

Свойства функции в JavaScript - это не переменные, а часть объекта функции, которая позволяет получить определенную информацию о функции.

70
Q

Какое свойство позволяет получить имя функции?

A

Свойство name позволяет получить имя функции в JavaScript.

71
Q

Может ли функция иметь пустое имя?

A

Да, если корректное имя функции определить невозможно, свойство name функции будет равно пустой строке.

72
Q

Какое свойство позволяет получить количество параметров функции в ее объявлении?

A

Свойство length.

73
Q

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

A

Да, можно. Например, можно создать свойство counter для подсчета количества вызовов функции.

74
Q

Какие преимущества имеет использование свойств функций вместо замыканий?

A

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

75
Q

Что такое NFE?

A

NFE - это Named Function Expression, т.е. функция, которой задано имя внутри выражения, а не в объявлении функции.
var f = function sayHi(…) { /* тело функции */ };

76
Q

Можно ли использовать NFE с Function Declaration?

A

Нет.

77
Q

Какое преимущество дает использование NFE перед обычным Function Expression при рекурсивных вызовах функции?

A

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

78
Q

Что такое синтаксис new Function и как он используется для создания функций?

A

Синтаксис new Function представляет собой способ создания функций в JavaScript путем передачи списка аргументов и кода функции в виде строки в конструктор Function. Этот способ может использоваться для создания функций на лету из динамически полученного кода или для динамической генерации функций во время выполнения программы.

79
Q

Как передаются аргументы в функцию, созданную с помощью синтаксиса new Function?

A

Аргументы передаются в виде строки, содержащей их имена, разделенные запятой, и функции, содержащей код, который будет выполняться при вызове функции.
let sum1 = new Function(‘a’, ‘b’, ‘return a + b’); // стандартный синтаксис
let sum2 = new Function(‘a,b’, ‘return a + b’); // через запятую в одной строке
let sum3 = new Function(‘a , b’, ‘return a + b’); // через запятую с пробелами в одной строке

80
Q

Можно ли создать функцию без аргументов с помощью синтаксиса new Function?

A

Да, передав пустую строку в качестве списка аргументов.
let sayHi = new Function(‘alert(“Hello”)’);

81
Q

Что такое ссылка [[Environment]] у функции в JavaScript?

A

Ссылка [[Environment]] у функции в JavaScript указывает на лексическое окружение, в котором функция была создана.

82
Q

Каково поведение функции, созданной с помощью new Function, в отношении лексического окружения?

A

У функции, созданной с помощью new Function, ссылка [[Environment]] указывает на глобальное лексическое окружение, а не на место, где функция была создана.

83
Q

Какой способ передачи параметров в new Function является предпочтительным?

A

Лучше явно передавать параметры в new Function, чтобы избежать проблем с минификаторами.

84
Q

Что такое минификатор?

A

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

85
Q

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

A

Метод setTimeout.

86
Q

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

A

Метод setInterval.

87
Q

Являются ли методы setTimeout и setInterval частью спецификации JavaScript?

A

Нет.

88
Q

Почему не рекомендуется передавать строку в метод setTimeout?

A

Лучше использовать функцию в качестве аргумента, чтобы избежать ошибок.

89
Q

Какие параметры можно передавать в метод setTimeout, кроме функции и интервала времени?

A

Можно передавать аргументы, которые будут переданы в вызываемую функцию.

90
Q

Какой синтаксис у метода setTimeout?

A

Синтаксис метода setTimeout выглядит так: let timerId = setTimeout(func|code, [delay], [arg1], [arg2], …)

91
Q

Как передать аргументы в функцию, которая будет вызвана через setTimeout?

A

Аргументы передаются через третий параметр метода setTimeout, например: setTimeout(sayHi, 1000, “Привет”, “Джон”);

92
Q

Можно ли использовать строку в качестве функции для метода setTimeout?

A

Да, можно использовать строку, но это не рекомендуется. Лучше передавать функцию или использовать функцию-стрелку, например: setTimeout(() => alert(‘Привет’), 1000);

93
Q

В чем заключается важное замечание относительно передачи функции в качестве аргумента метода setTimeout?

A

Необходимо передавать функцию, а не ее результат, например: setTimeout(sayHi, 1000), а не setTimeout(sayHi(), 1000).

94
Q

Как можно использовать возвращаемое значение от setTimeout?

A

setTimeout возвращает уникальный идентификатор таймера, который можно использовать в методе clearTimeout для отмены запланированного вызова функции.

95
Q

Можно ли отменить запланированный вызов функции, если не сохранять id таймера?

A

Нет, для отмены запланированного вызова функции необходимо иметь id таймера, который был возвращен при вызове setTimeout.

96
Q

Можно ли использовать clearTimeout для остановки setInterval?

A

Нет, для остановки setInterval нужно использовать clearInterval, который принимает в качестве аргумента id интервала.

97
Q

Можно ли использовать clearTimeout для остановки запущенной функции?

A

Нет, clearTimeout используется для отмены запланированного вызова функции, а не для остановки функции, которая уже была вызвана. Если функция уже была вызвана, то ее выполнение может быть прервано только при помощи оператора return или внутренней логики функции.

98
Q

Как работает функция setInterval()?

A

setInterval() запускает функцию или код через указанный интервал времени несколько раз, пока не будет отменен. Между каждым запуском функции проходит не равное количество времени, потому что время работы функции тоже учитывается в интервале. Если необходимо сделать равные интервалы между запусками функции, можно использовать вложенный setTimeout().

99
Q

Как остановить выполнение функции, запущенной через setInterval()?

A

Для остановки выполнения функции, запущенной через setInterval(), нужно вызвать clearInterval() и передать ему идентификатор таймера, возвращаемый setInterval().

100
Q

Можно ли передать аргументы в функцию, вызываемую через setInterval()?

A

Да, можно передать аргументы в функцию, вызываемую через setInterval(). Аргументы передаются после указания интервала времени, разделенные запятой. Например: setInterval(myFunc, 1000, arg1, arg2).

101
Q

Чем отличается вложенный setTimeout от setInterval?

A

Вложенный setTimeout позволяет задавать разный интервал времени между запусками функции, в то время как setInterval имеет фиксированный интервал.

102
Q

Какой пример можно привести для использования вложенного setTimeout вместо setInterval?

A

Можно использовать вложенный setTimeout для создания функционала, аналогичного setInterval. Например, вместо использования setInterval для вывода сообщения “tick” каждые 2 секунды, можно использовать следующий код:
let timerId = setTimeout(function tick() {
alert(‘tick’);
timerId = setTimeout(tick, 2000);
}, 2000);

103
Q

Как можно настроить интервалы времени с помощью вложенного setTimeout?

A

Интервалы времени могут быть настроены непосредственно в коде функции обратного вызова, которая передается внутрь setTimeout. Например, можно написать сервис, который отправляет запросы на сервер каждые 5 секунд, но в случае перегрузки сервера интервалы увеличиваются до 10, 20, 40 секунд. Для этого можно использовать следующий код:
let delay = 5000;
let timerId = setTimeout(function request() {
// отправить запрос
// …
if (ошибка запроса из-за перегрузки сервера) {
// увеличить интервал для следующего запроса
delay *= 2;
}
timerId = setTimeout(request, delay);
}, delay);

104
Q

Каким образом можно остановить вложенный setTimeout?

A

Для остановки вложенного setTimeout необходимо вызвать функцию clearTimeout, передав в нее идентификатор таймера, который был возвращен при создании вложенного setTimeout. Например:
let timerId = setTimeout(function tick() {
alert(‘tick’);
timerId = setTimeout(tick, 2000);
}, 2000);
// остановить таймер через 10 секунд
setTimeout(function() {
clearTimeout(timerId);
}, 10000);

105
Q

Что происходит с функцией, переданной в setTimeout, после её выполнения?

A

Функция, переданная в setTimeout, не будет автоматически удалена из памяти после её выполнения. Она будет оставаться в памяти до тех пор, пока планировщик не вызовет её ещё раз или пока её ссылка не будет удалена вручную.

106
Q

Можно ли предотвратить утечку памяти при использовании setInterval, не вызывая clearInterval?

A

Нет, нельзя предотвратить утечку памяти при использовании setInterval, если не вызывать clearInterval. Функция, переданная в setInterval, будет оставаться в памяти до тех пор, пока она не будет удалена путём вызова clearInterval.

107
Q

Какие проблемы могут возникнуть при неотмененном setInterval или setTimeout?

A

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

108
Q

Какой параметр у функции setTimeout является необязательным и равен по умолчанию 0?

A

Параметр delay.

109
Q

Что произойдет при вызове функции setTimeout с задержкой 0 мс?

A

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

110
Q

Какие будут результаты выполнения следующего кода:
setTimeout(() => alert(“Мир”));
alert(“Привет”);

A

Сначала будет выведено “Привет”, затем “Мир”, потому что первая строка помещает вызов функции в «календарь» через 0 мс, но планировщик проверит «календарь» только после того, как текущий код завершится. Поэтому “Привет” выводится первым, а “Мир” – после него.

111
Q

Что такое ограничение на частоту выполнения внутренних счётчиков в браузере?

A

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

112
Q

Почему ограничение на частоту выполнения внутренних счётчиков сохраняется по историческим причинам?

A

Многие скрипты полагаются на ограничение на частоту выполнения внутренних счётчиков в браузере, поэтому это ограничение сохраняется по историческим причинам.

113
Q

Есть ли ограничение на частоту выполнения внутренних счётчиков в серверном JavaScript?

A

Нет, этого ограничения нет в серверном JavaScript. Там есть и другие способы планирования асинхронных задач, такие как setImmediate для Node.js. Это ограничение относится только к браузерам.

114
Q

Какую проблему решают декораторы?

A

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

115
Q

Какую особенность имеют декораторы в JavaScript?

A

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

116
Q

Что такое прозрачное кеширование?

A

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

117
Q

Как можно реализовать прозрачное кеширование в JavaScript?

A

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

118
Q

Как можно решить проблему потери контекста при передаче метода объекта в декоратор?

A

Проблему потери контекста можно решить, передавая контекст объекта в вызываемую функцию с помощью метода call. Например, можно вызвать функцию с помощью func.call(this, arg1, arg2, …), где this - контекст объекта, а arg1, arg2 и т.д. - аргументы, передаваемые в вызываемую функцию.

119
Q

Что такое spread-оператор, и как его можно использовать в декораторах?

A

Spread-оператор - это оператор “…” внутри вызова функции или конструктора, который позволяет передавать массив как список аргументов. В декораторах spread-оператор можно использовать для раскрытия аргументов переданной в декоратор функции. Например, можно вызвать функцию с помощью func.call(this, …arguments), где this - контекст объекта, а arguments - массив аргументов, передаваемых в вызываемую функцию.

120
Q

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

A

Для того чтобы сделать декоратор универсальным и применимым к функциям с любым количеством аргументов, можно использовать массив arguments, который содержит все переданные аргументы. Например, можно вызвать функцию с помощью func.call(this, …arguments), где this - контекст объекта, а …arguments - раскрытие массива аргументов, передаваемых в вызываемую функцию.

121
Q

Какие аргументы принимает метод apply()?

A

Метод apply() принимает два аргумента: контекст и псевдомассив аргументов.

122
Q

В чем разница между методами call() и apply()?

A

Основная разница между методами call() и apply() заключается в способе передачи аргументов. Метод call() принимает аргументы в виде списка (то есть каждый метод записывается через запятую, либо с помощью spread-оператора), а метод apply() принимает аргументы в виде псевдомассива.

123
Q

Для чего используется перенаправление вызова (call forwarding)? Пример.

A

Перенаправление вызова (call forwarding) используется для передачи всех аргументов вместе с контекстом другой функции.
let wrapper = function() {
return func.apply(this, arguments);
};

124
Q

Если можно использовать оба метода (call/apply), то какой лучше использовать?

A

Лучше использовать apply, так как движки оптимизируют его лучше.

125
Q

Почему метод join нельзя вызвать напрямую от итерируемого объекта/псевдомассива?

A

Метод join не доступен для итерируемых объектов/псевдомассивов, так как он работает с контекстом (this), который для них не задан.

126
Q

Каким образом можно использовать метод join с псевдомассивом/итерируемым объектом?

A

Можно использовать заимствование метода, вызывая метод join у пустого массива и передавая контекст в виде итерируемого объекта/псевдомассива, например: [].join.call(arguments).

127
Q

Чем отличаются функции привязки call/apply от функции привязки bind/bindAll?

A

call/apply вызывают на месте эту же функцию с привязкой, а bind/bindAll создают копию функции с привязкой, чтобы ее можно было использовать позже.

128
Q

Какие решения есть для проблемы потери this при передаче метода отдельно от объекта?

A

Для решения проблемы потери this можно использовать функцию-обертку или функцию привязки bind.

129
Q

Какое значение this устанавливает метод setTimeout в браузере для вызова функции?

A

Метод setTimeout в браузере устанавливает значение this равным глобальному объекту window для вызова функции.

130
Q

Какое значение this устанавливает метод setTimeout в Node.js для вызова функции?

A

В Node.js метод setTimeout устанавливает значение this равным объекту таймера для вызова функции.

131
Q

Почему функция-обертка и метод bind используются для решения проблемы потери this?

A

Функция-обертка и метод bind используются для того, чтобы связать this с нужным объектом. При передаче метода отдельно от объекта, this теряет связь с объектом, и его значение становится равным глобальному объекту window (или undefined). Чтобы сохранить связь с объектом, используются функция-обертка и метод bind, которые создают новую функцию с привязанным this к нужному объекту.

132
Q

Чем отличается решение 1 (функция-обертка) от решения 2 (привязка контекста с помощью bind)?

A

Решение 1 заключается в обертывании вызова метода объекта в анонимную функцию, создавая замыкание, в то время как решение 2 использует метод bind для привязки контекста, гарантируя, что вызов метода объекта будет возвращать ожидаемый результат, даже если объект будет изменен.

133
Q

Что такое “экзотический объект” при использовании метода bind?

A

“Экзотический объект” - это объект, создаваемый при использовании метода bind, который вызывается как функция и прозрачно передает вызов в оригинальную функцию, при этом устанавливая контекст выполнения в указанное значение this.

134
Q

Как использование метода bind может помочь в работе с методами объектов?

A

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

135
Q

Можно ли использовать метод bind для передачи дополнительных аргументов в функцию при вызове метода объекта?

A

Да, метод bind может быть использован для частичного применения функции, что позволяет передать дополнительные аргументы в функцию при вызове метода объекта. При этом переданные аргументы будут переданы в функцию такими, какими они есть.

136
Q

Какое назначение у функции bind()?

A

Функция bind() привязывает контекст и начальные аргументы функции, создавая новую функцию, которую можно вызывать отдельно.

137
Q

Как называется процесс создания новой функции с фиксированными начальными аргументами?

A

Этот процесс называется частичное применение.

138
Q

Как применить частичное применение для функции умножения mul(a, b), чтобы создать функцию double для удвоения числа?

A

Можно использовать функцию bind() следующим образом: let double = mul.bind(null, 2);

139
Q

Как можно использовать частичное применение для создания более специализированной версии общей функции?

A

Можно использовать частичное применение для фиксации некоторых параметров общей функции и создания новой функции с более узкой специализацией. Например, можно создать функцию sendTo(to, text), которая является частным вариантом функции send(from, to, text).

140
Q

Что такое частичное применение функции?

A

Частичное применение функции - это процесс создания новой функции путем фиксации некоторых аргументов оригинальной функции.

141
Q

Как работает функция partial из библиотеки lodash?

A

Функция partial принимает функцию и аргументы для фиксации. Она возвращает анонимную функцию, которая вызывает оригинальную функцию с фиксированными аргументами при помощи метода call.

142
Q

Можно ли использовать встроенный метод bind для частичного применения функции без задания контекста?

A

Нет, встроенный метод bind требует задания контекста при фиксации аргументов.

143
Q

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

A

Можно создать анонимную функцию, которая вызывает оригинальную функцию с фиксированными аргументами при помощи метода apply, как это делает функция partial в примере выше.

144
Q

Что такое стрелочные функции и как они отличаются от обычных функций?

A

Стрелочные функции - это функции в JavaScript, которые не имеют своего this, не могут быть вызваны с new и не имеют псевдомассива “arguments”. Они отличаются от обычных функций тем, что при обращении к this, его значение берется из внешнего лексического окружения.

145
Q

Можно ли использовать стрелочные функции как конструкторы?

A

Нет, стрелочные функции не могут быть использованы как конструкторы и не могут быть вызваны с new.

146
Q

Что такое псевдомассив “arguments” и почему его нет у стрелочных функций?

A

Псевдомассив “arguments” - это массивоподобный объект, который содержит аргументы, переданные в функцию. У стрелочных функций нет псевдомассива “arguments”, потому что они не имеют своего this и не могут быть вызваны с new.

147
Q

В чем отличие между использованием bind и стрелочных функций для привязки контекста?

A

Метод bind создает “связанную версию” функции, которая привязывает значение this к указанному объекту. Стрелочные функции не привязывают this и не имеют своего this, вместо этого они берут значение this из внешнего лексического окружения.

148
Q

Можно ли использовать стрелочные функции для наследования классов?

A

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