slide-e48574c0-ea10-48ab-b016-bcdf933a6c0a

Области видимости в JS

Хочу затронуть базу. Это очень любопытная тема, в которой путаются даже опытные разработчики. А все почему? Да потому что мы редко сталкиваемся с этим [за исключением блочной, разумеется] в реальной работе, и в конечном итоге это либо забывается, либо мы начинаем путаться в понятиях. Откуда появились функциональная и блочная области видимости? На раннем этапе JS использовали для написания простых скриптов, и не предполагалось создавать большие вложенные структуры кода. Со временем JavaScript эволюционировал, и с появлением стандарта ECMAScript 6 появились let и const. Вероятно, это было сделано для большей предсказуемости и изоляции кода. Да и конкуренцию с другими языками никто не отменял. Принято считать, что у нас есть 3 области видимости. 1. Глобальная область видимости. Переменные, объявленные вне функций и блоков, доступны повсюду в коде. В браузере это объект window, в Node.js — global. Старайтесь избегать подобных объявлений, так как это загрязняет глобальное пространство имен и может привести к конфликтам. 2. Функциональная область видимости. Переменные, объявленные внутри функций, доступны только в ее пределах и в ее вложенностях. Если с let и const тут всё понятно, то у var есть важная особенность: переменная, созданная внутри блока if или цикла for, будет доступна и после этого блока (в пределах всей функции). Это происходит из-за того, что var поднимается в начало своей области видимости (функции) и определяется как undefined до момента инициализации. 3. Блочная область видимости. Переменные, объявленные через let и const, доступны только в границах блока {...}, где они объявлены, и ниже по вложенности. Теперь небольшой, но важный момент про поднятие (hoisting). · let, const, var — все они поднимаются (hoisted) в начало своей области видимости. Однако let и const до момента объявления попадают во временную мертвую зону (Temporal Dead Zone). Попытка обратиться к ним до строки объявления приведет к ошибке ReferenceError. · Function Declaration (объявление функции через function foo() {}) — полностью поднимается в начало своей области видимости. Такую функцию можно вызвать до её объявления в коде. · С Function Expression (присвоение функции переменной) есть нюанс, который необходимо знать: getData() // Ошибка var getData = function() { console.log('получил данные') } Переменная getData (через var) поднимется в начало области видимости. До момента выполнения кода инициализации её значение будет undefined. А попытка вызвать undefined как функцию приведет к ошибке. Для let и const с Function Expression ошибка была бы на этапе обращения (из-за TDZ), а не на попытке вызова. В заключение хотелось бы сказать: навряд ли эта тема коснется кого-то из современных разработчиков в виде внезапных ошибок, но эти знания необходимы для лучшего понимания устройства нашего любимого языка.