Что такое цепочка областей видимости в JS?

Цепочка областей видимости в JavaScript — фундаментальная концепция, влияющая на доступ к переменным и их разрешение в программе.

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

При доступе к переменной механизм JavaScript начинает искать ее в текущей области, а затем следует по цепочке родительских областей до тех пор, пока не будет найдена переменная или пока она не достигнет глобальной области.

Типы цепочек областей действия

В JavaScript есть разные типы цепочки областей видимости. Давайте подробно рассмотрим каждый тип цепочки областей видимости с наглядными примерами.

Глобальный охват:

Глобальная область видимости — это самая внешняя область действия в программе JavaScript. Переменные, объявленные вне каких-либо функций или блоков, относятся к этой области видимости и могут быть доступны из любой части программы.

const globalVar = 'I am in the global scope';

function printGlobalVar() {
  console.log(globalVar);
}

printGlobalVar(); // Output: "I am in the global scope"
console.log(globalVar); // Output: "I am in the global scope"

В этом примере globalVar объявлен в глобальной области видимости, поэтому он доступен как внутри функции printGlobalVar, так и вне ее.

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

Когда функция определена, она создает свою собственную локальную область. Переменные, объявленные внутри функции с помощью ключевых слов var, let или const, доступны только в пределах области видимости этой функции. Если переменная не найдена в локальной области видимости, JavaScript перемещается вверх по цепочке областей видимости, чтобы искать ее в следующей внешней области.

function outerFunction() {
  const outerVar = 'I am in the outer function';

  function innerFunction() {
    console.log(outerVar);
  }

  innerFunction(); // Output: "I am in the outer function"
}

outerFunction();
console.log(outerVar); // Error: outerVar is not defined

Здесь externalVar объявляется внутри externalFunction, создавая локальную область. innerFunction может получить доступ к externalVar, так как он является частью своей цепочки лексических областей видимости.

Объем блока:

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

if (true) {
  let blockVar = 'I am in the block scope';
  console.log(blockVar); // Output: "I am in the block scope"
}

console.log(blockVar); // Error: blockVar is not defined

В этом случае blockVar объявляется с let внутри блока. В результате он доступен только внутри блока, а не за его пределами.

Лексический охват:

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

function outerFunction() {
  const outerVar = 'I am in the outer function';
  
  if (true) {
    const innerVar = 'I am in the inner block';
    console.log(outerVar); // Output: "I am in the outer function"
    console.log(innerVar); // Output: "I am in the inner block"
  }

  console.log(outerVar); // Output: "I am in the outer function"
  console.log(innerVar); // Error: innerVar is not defined
}

outerFunction();

Здесь у нас есть область видимости функции (внешняя переменная) и область видимости блока (внутренняя переменная) внутри одной и той же внешней функции. В то время как externalVar доступен во всей функции, innerVar доступен только внутри блока, где он определен.

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

function outerFunction() {
  const outerVar = 'I am in the outer scope';  
  
  function closureFunction() {
    // Forms a closure, accessing outerVar from the outer scope
    console.log(outerVar);
  }

  return closureFunction;
}

const closure = outerFunction();

// Closure retains access to outerVar
// even after outerFunction has finished executing.
closure(); // Output: "I am in the outer scope"

Краткое содержание

Цепочка областей видимости — это фундаментальная концепция в JavaScript, которая играет решающую роль в доступе к переменным и их разрешении во время выполнения кода.

Области действия в JavaScript включают глобальную область, область действия функции и область действия блока, каждая из которых влияет на доступ к переменным. Кроме того, лексическая область видимости вводит понятие замыканий.

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