Это мои заметки к курсу Advanced Javascript Асима Хуссейна (https://medium.com/@jawache). Проверьте это здесь: https://www.udemy.com/javascript-advanced/

Каковы различные области видимости в Javascript?

Достаточно просто: глобальный, локальный и блочный.

Цитируя Хуссейна: «Область действия — это время жизни переменной, то есть когда эта переменная видна и доступна для использования в вашем коде».

Вы можете объявить глобальную переменную, объявив ее лексически как таковую (то есть не внутри функции или объекта) или объявив ее как часть windowobject. В браузерном Javascript все глобальные переменные назначаются объекту windowobject.

Локальная или блочная область видимости

Если вы объявляете переменную внутри функции (т. е. локальную переменную), она недоступна вне функции. Но как насчет цикла for?

В других языках с областью действия на уровне блоков переменные i и j будут видны только внутри блока цикла for. В Javascript не было областей на уровне блоков до появления let в ES6.

Что такое переменный подъем?

Рассмотрим следующий код:

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

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

И все же, если мы объявляем переменную как функцию, Javascript обрабатывает ее как объявление переменной. Итак, этот код:

Эквивалентно:

Что такое цепочка областей?

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

Мы должны устранить эту ошибку, лексически объявив foo внутри области видимости, в которой myVar. Вот некоторые примеры:

Что такое IIFE и почему вы можете его использовать?

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

Рассмотрим HTML, который загружает два файла Javascript:

Если мы загрузим веб-страницу и журнал консоли thing, мы увидим:

{hello: "other"}

Глобальная переменная thing в otherADVJS.js переопределяет переменную в mainADVJS.js. Если мы этого не ожидаем, это может вызвать проблемы позже. Как правило, мы хотим избегать глобальных переменных, и мы можем сделать это с помощью IIFE.

Что такое замыкание функций?

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

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

Канонический цикл for

Рассмотрим код:

Этот код создает массив функций, каждая из которых возвращает свой индекс массива. Но это не так. Вывод этого кода на самом деле:

10
10
10

Каждый return i в функциях foo указывает не на моментальный снимок i во время создания функций, а на фактическое значение i во время их вызова (10). Как мы можем это исправить? Одним из решений является использование IIFE, каждый из которых создает свою собственную версию локальной переменной y.

Мы можем переписать этот код, передавая i в качестве аргумента IIFE:

Или, конечно, мы можем просто использовать let и вообще забыть об этом безумии:

Надеюсь, это поможет!