Старая школа JavaScript
Традиционно JavaScript действительно имеет только два типа области действия:
- Global Scope : Переменные известны в приложении с самого начала приложения (*)
- Функциональная область : переменные известны в функции , в которой они объявлены, с начала функции (*)
Я не буду подробно останавливаться на этом, поскольку уже есть много других ответов, объясняющих разницу.
Современный JavaScript
Самые последние спецификации JavaScript теперь также допускают третью область:
- Область действия блока : переменные известны в блоке , в котором они объявлены, с момента их объявления (**)
Как создать переменные области видимости блока?
Традиционно вы создаете переменные следующим образом:
var myVariable = "Some text";
Переменные области видимости создаются следующим образом:
let myVariable = "Some text";
Так в чем же разница между функциональной областью и областью блока?
Чтобы понять разницу между функциональной областью и областью блоков, рассмотрим следующий код:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
Здесь мы видим, что наша переменная j
известна только в первом цикле for, но не до и после. Тем не менее, наша переменная i
известна во всей функции.
Кроме того, учтите, что переменные в области блока не известны до того, как объявлены, потому что они не подняты. Вам также не разрешается повторно объявлять одну и ту же переменную области действия блока в одном и том же блоке. Это делает переменные области блока менее подверженными ошибкам, чем переменные глобальной или функциональной области, которые поднимаются и не приводят к ошибкам в случае нескольких объявлений.
Безопасно ли сегодня использовать переменные области видимости блока?
Безопасно ли сегодня использовать, зависит от вашей среды:
Если вы пишете код JavaScript на стороне сервера ( Node.js ), вы можете смело использовать оператор let
.
Если вы пишете код JavaScript на стороне клиента и используете браузер на основе транспилятора (например, Traceur или babel-standalone ), вы можете смело использовать оператор let
, однако ваш код может быть не оптимальным с точки зрения производительности.
Если вы пишете код JavaScript на стороне клиента и используете транспортер на основе Node (например, сценарий оболочки traceur или Babel ), вы можете смело использовать оператор let
. А поскольку ваш браузер будет знать только о переданном коде, недостатки производительности должны быть ограничены.
Если вы пишете код JavaScript на стороне клиента и не используете транспортер, вам следует подумать о поддержке браузера.
Это некоторые браузеры, которые вообще не поддерживают let
:
- Internet Explorer 10 и ниже
- Firefox 43 и ниже
- Safari 9 и ниже
- Android-браузер 4 и ниже
- Опера 27 и ниже
- Chome 40 и ниже
- ЛЮБАЯ версия Opera Mini & Blackberry Browser
Как отслеживать поддержку браузера
Обновленный обзор того, какие браузеры поддерживают оператор let
на момент прочтения этого ответа, см. На этой Can I Use
странице .
(*) Глобальные и функциональные переменные могут быть инициализированы и использованы до их объявления, потому что переменные JavaScript hoisted . Это означает, что объявления всегда много к вершине области.
(**) Переменные области видимости не перемещаются