В этой статье предполагается, что вы хорошо понимаете переменные и различные способы объявления переменных в JavaScript, поскольку эти понятия рассматриваться не будут.
Что такое область видимости?
Область действия определяет доступность (видимость) переменных. Область видимости определяет, где переменная будет доступна и как долго будет сохраняться ее определение. В JavaScript существует три типа области видимости: Глобальная область видимости, локальная область видимости и область видимости блока.
Глобальная область видимости
Глобальная область видимости — это область видимости по умолчанию для всех кодов, выполняемых в режиме сценария. Переменные, объявленные вне любой функции или блока кода, становятся глобальными переменными и доступны из любой точки кода. Во всей программе существует одна копия глобальной переменной.
// global scope
var name = 'Sophia'
console.log(name); //Sophia
function getName(){
console.log(name) //name is accessible here
}
getName() //Sophia
Переменные, определенные вне любой функции, становятся глобальными переменными и также могут быть изменены из любой функции. Возьмем нашу предыдущую переменную name:
// global scope
var name = 'Sophia'
console.log(name); //Sophia
function getName(){
console.log(name) //name is accessible here
}
function changeName(){
name = 'Jane'
console.log(name) //name is accessible here
}
getName() //Sophia
changeName() //Jane
Изменение значения глобальной переменной в любой функции будет отражено во всей программе. Мы уже видим, почему не стоит объявлять глобальные переменные непреднамеренно.
Локальная область видимости
Локальная область видимости также может называться областью видимости функции. Функция создает область видимости, и переменные, объявленные в этой функции, становятся локальными для этой функции и не могут быть доступны за ее пределами. Рассмотрим следующий пример:
//Local Scope
function getName(){
var name = 'Sophia';
console.log(name) //name can only used in getName
}
getName() //Sophia
console.log(name); //Causes error
Локальные переменные доступны только внутри своих функций, что означает, что переменные с одинаковыми именами могут использоваться в разных функциях, и их значения не будут перезаписаны. Локальные переменные создаются при запуске функции и удаляются после ее завершения.
//Local Scope
function getName(){
var name = 'Sophia';
console.log(name)
}
function getOtherName(){
var name = 'Xavier';
console.log(name)
}
getName() //Sophia
getOtherName() //Xavier
Теперь посмотрите на этот пример кода:
function createCounter(){
count = 0;
}
function incrementCounter(){
return ++count;
}
Какова область видимости переменной count
выше и будет ли работать функция incrementCounter
?
Прежде чем ответить, обратите внимание, что JavaScript не требует объявления переменных перед их использованием, а необъявленные переменные помещаются в глобальную область видимости. Дайте мне знать ваш ответ в разделе комментариев.
Область видимости блока
До появления ES6 (2015) в JavaScript существовали только локальная (функциональная) область видимости и глобальная область видимости. С введением let
и const
появилась блочная область видимости. Область блоков — это просто область внутри операторов if
, switch
и loops
. Блок обычно заключен в фигурные скобки { }
.
Переменные, объявленные внутри блока { }
, не могут быть доступны вне этого блока.
//Block Scope
function getName(){
for(let count = 1; count <= 10; count +=1){
//count is accessible here
}
//count is not accessible here
}
Переменная count появляется при входе в блок цикла и уничтожается при выходе из него. Обратите внимание, что в блоках доступны только переменные, объявленные с помощью let
и const
.
В целом, область видимости — это то, что контролирует доступность переменных. Глобальные переменные всегда существуют и доступны во всей программе. Переменные блоков и функций доступны только в том блоке/функции, в котором они объявлены.
Обратите внимание, что существует концепция закрытия, которая позволяет обращаться к переменным за пределами локальной области видимости. Более подробно о замыканиях будет рассказано в моей следующей статье.