Понимание области действия функции и области действия блока в Javascript

Версия TL; DR

В Javascript можно определять переменные с помощью ключевых слов var, let или const.

var a=10;
let b=20;
const PI=3.14;

var: Объем переменной, определенной с помощью ключевого слова «var», ограничен «функцией», в которой она определена. Если переменная определена вне какой-либо функции, область видимости переменной будет глобальной.
var имеет «область видимости функции».

let: Объем переменной, определенной с помощью ключевого слова let или const, ограничен «блоком», определяемым фигурными скобками, то есть {}.
«Let» и «const» являются «блочными».

const: Объем переменной, определенной с помощью ключевого слова «const», ограничен блоком, определяемым фигурными скобками. Однако, если переменная определена с ключевым словом const, ее нельзя переназначить.
«const» нельзя переназначить новому значению. Однако он МОЖЕТ быть изменен.

Область действия функции и область действия блока

Давайте разберемся в этом на некоторых примерах кода,

Область действия блока

В Javascript вы можете определить блок кода, используя фигурные скобки, т.е. {}.
Рассмотрим следующий код, состоящий из 2 блоков кода, каждый из которых разделен знаком {}.

{
  var a=10;
  console.log(a);
} //block 1
{
  a++;
  console.log(a);
} //block 2
/* Since we are using "var a=10", scope of "a" is limited to the function within which it is defined. In this case it is within the global function scope */

В приведенном выше примере, поскольку мы используем ключевое слово var для определения переменной a, область действия a ограничена функцией, в которой она определена. Поскольку a не определен ни в одной функции, область видимости переменной a является глобальной, что означает, что a распознается в блоке 2.

Фактически, если переменная определена с ключевым словом var, Javascript не распознает {} в качестве ограничителя области видимости. Вместо этого переменная должна быть заключена в «функцию», чтобы ограничить ее объем этой функции.

Давайте перепишем приведенный выше код, используя ключевое слово let.
Ключевое слово let было введено как часть синтаксиса ES6 как альтернатива var для определения переменных в Javascript.

{
 let a=10;
 console.log(a);
} //block 1
{
  a++;
  console.log(a);
} //block 2
/* Since we are using "let a=10", scope of "a" is limited to block 1 and "a" is not recognized in block 2 */

Обратите внимание, что теперь, когда вы запустите приведенный выше код, вы получите сообщение об ошибке: переменная a не распознается в блоке 2. Это связано с тем, что мы определили переменную a с помощью ключевого слова let, которое ограничивает область действия переменной a блоком кода, в котором она была определена.

Объем функции

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

Ключевое слово var ограничено функцией, т.е. оно не распознает фигурные скобки, то есть {}, как разделители. Вместо этого он распознает тело функции как разделитель.

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

function block1() {
var a=10;
 console.log(a);
} //function scope of block 1
function block2() {
  a++;
  console.log(a);
} //function scope of block 2
/* Since we have enclosed block1 and block2, within separate functions, the scope of "var a=10", is limited to block 1 and "a" is not recognized in block 2 */

Приведенный выше код действует так же, как если бы мы использовали let a=10 вместо var a=10. Область действия переменной a ограничена функцией, в которой она определена, и a больше не находится в глобальном пространстве имен.

Почему вы выбрали «let» вместо «var»?

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

В прошлом, до того как ключевое слово let было введено как часть ES6, чтобы обойти проблему определения области видимости переменных с помощью var, программисты использовали шаблон IIFE для предотвращения загрязнения глобального пространства имен. Однако с момента появления let шаблон IIFE больше не требуется, а область действия переменной, определенной с помощью let, ограничена блоком кода, в котором он определен.

Для получения дополнительной информации: Что такое IIFE в Javascript?

Ключевое слово «const»

Если переменная определяется с помощью ключевого слова const, ее область действия ограничивается областью блока. Кроме того, переменной нельзя присвоить другое значение.

{
 const PI=3.14;
 console.log(PI);
} //block 1
{
  console.log(PI);
} //block 2
/* Since we are using "const PI=3.14", scope of "PI" is limited to block 1 and "PI" is not recognized in block 2 */

Обратите внимание, что важно понимать, что const НЕ означает, что значение является фиксированным и неизменным. Это распространенное недоразумение среди многих разработчиков Javascript, и они неправильно упомянули, что значение, определенное ключевым словом const, является неизменным (т.е. его нельзя изменить).

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

{
 const a = [1,2,3];
 const b = {name: "hello"};
 a.push(4,5);     //mutating the value of constant "a"
 b.name="World";  //mutating the value of constant "b"
 
 console.log(a); //this will show [1,2,3,4,5]
 console.log(b); //this will show {name: "World"}
 
}
/* This code will run without any errors, and shows that we CAN mutate the values that are defined by "const" */

Однако обратите внимание, что эти переменные, определенные const, не могут быть переназначены.

{
 const name = "Mike";
 const PI = 3.14; 
 const a = [1,2,3];
 const b = {name: "hello"};
 
 name="Joe"; 
//this will throw an error, since we are attempting to re-assign "name" to a different value.
 PI = PI + 1; 
//this will throw an error, since we are attempting to re-assign PI to a different value.
 a = [1,2,3,4,5];
//this will throw an error, since we are attempting to re-assign "a" to a different value.
 b = {name: "hello"};
//this will throw an error, since we are attempting to re-assign "b" to a different value.
}

Резюме

var - это функциональная область

let, const являются областью BLOCK

const, нельзя переназначить, однако он изменяемый

Нашли это полезным? Нажмите кнопку 👏 , чтобы показать, насколько вам это понравилось! 🙂

Следите за мной на Medium, чтобы получать последние обновления и сообщения!

Читать дальше: Объяснение обещаний в Javascript!

Другие статьи: