Синтаксис JavaScript Справочник JavaScript JSON Коды клавиш События Строгий режим

JavaScript: Область видимости переменных

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

Глобальные переменные

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

var num = 5;

function foo() {
  console.log(num);
}

foo();                // 5
console.log(num);     // 5
{
  console.log(num);   // 5
}

Локальные переменные

Переменная, объявленная внутри функции, называется локальной. Локальная переменная доступна в любом месте внутри тела функции, в которой она была объявлена. Локальная переменная создаётся каждый раз заново при вызове функции и уничтожается при выходе из неё (при завершении работы функции):

function foo() {
  var num = 5;
  console.log(num);
}

foo();                     // 5
console.log(typeof num);   // undefined

Локальная переменная имеет преимущество перед глобальной переменной с тем же именем, это означает, что внутри функции будет использоваться локальная переменная, а не глобальная:

var x = "глобальная";   // Глобальная переменная

function checkscope() {
  var x = "локальная";  // Локальная переменная с тем же именем, что и у глобальной
  document.write(x);    // Используется локальная переменная, а не глобальная
}

checkscope();           // => "локальная"
Попробовать »

Блочные переменные

Переменная, объявленная внутри блока с помощью ключевого слова let, называется блочной. Блочная переменная доступна в любом месте внутри блока, в котором она была объявлена:

let num = 0;
{
  let num = 5;
  console.log(num);     // 5
  {
    let num = 10;
    console.log(num);   // 10
  }
  console.log(num);     // 5
}
console.log(num);       // 0

Повторное объявление

Если с помощью ключевого слова var повторно объявить переменную с тем же именем (в той же области видимости), то ничего не произойдёт:

var a = 10;
var a;
console.log(a);   // 10

Если повторное объявление сопровождается инициализацией, то такая инструкция действует как обычное присваивание нового значения:

var a = 10;
var a = 5;        // Тоже самое, что и a = 5;

console.log(a);   // 5

Если с помощью ключевого слова let повторно объявить переменную с тем же именем (в той же области видимости), то будет вызвана ошибка:

var a = 10;
let a;   // Ошибка.

Цепочка областей видимости

Рассмотрим следующий пример:

var num = 5;

function foo() {
  var num2 = 10;

  function bar() {
    var num3 = 15;
  }
}

В этом коде три области видимости: глобальная, область видимости функции foo() и область видимости функции bar(). В глобальной области видимости определены переменная num и функция foo(). В области видимости функции foo() определены переменная num2 и функция bar(), в ней также доступна переменная num из глобальной области видимости. Область видимости функции bar() содержит одну переменную num3, которая доступна только внутри функции bar(). В области видимости функции bar() также доступны переменные из двух других областей, потому что они являются родительскими по отношению к ней. Цепочка областей видимости для этого примера представлена на рисунке ниже:

JavaScript: цепочка областей видимости

На рисунке разные области видимости показаны прямоугольниками разного цвета. Внутренней области видимости в цепочке областей видимости доступно всё из внешних областей, но внешним областям не доступно ничего из внутренних областей видимости.

Цепочка областей видимости упорядочена. Интерпретатор производит поиск идентификаторов в цепочке областей видимости по направлению наружу, но не внутрь. Это означает, что поиск имени начинается с той области видимости, где было выполнено обращение к идентификатору. Если имя идентификатора обнаруживается, поиск прекращается. Если в текущей области видимости найти имя не удалось, выполняется поиск в следующей (во внешней) области видимости и т. д. Таким образом, будет использован идентификатор из той области видимости, в которой был найден. Если идентификатор не будет найден ни в одной из областей видимости JavaScript сгенерирует ошибку:

var str = "глобальная";
var num = 5;

function foo() {
  var str = "локальная";   // Используется локальная переменная str
  num = 10;                // Используется глобальная переменная num
  // alert(x);     // Ошибка. Переменной x нет ни в одной области видимости
}

foo();
alert(str);   // "глобальная"
alert(num);   // 10

Если в теле функции необъявленной переменной присвоить значение то, в момент вызова функции, если в глобальной области видимости нет переменной с таким именем, будет создана новая глобальная переменная:

function foo() {
  num = 2;
}

foo();           // Создана новая глобальная переменная num
alert(num);      // 2

Подъём объявлений

В JavaScript объявленные переменные доступны в любом месте относительно своей области видимости, это означает, что переменные оказываются видимы ещё до того, как будут объявлены в коде. Эта особенность JavaScript неофициально называется подъёмом: программный код ведёт себя так, как если бы объявления переменных неявно поднимались (без инициализации) на самый верх относительно своей области видимости.

Рассмотрим следующий фрагмент кода:

var str = "глобальная";
function foo() {
  alert(str);   // undefined
  var str = "локальная";
  alert(str);   // "локальная"
}
foo();

Посмотрев на код, можно было бы подумать, что первый alert должен вывести строку "глобальная", потому что объявление локальной переменной str ещё не было выполнено. Однако, на деле выводится значение undefined. Благодаря подъёму объявлений функция выше эквивалентна реализации, приведённой ниже, в которой объявление переменной поднято в начало функции:

function foo() {
  var str;            // Объявление локальной переменной в начале функции
  alert(str);         // Здесь она доступна, но не инициализирована
  str = "локальная";  // Здесь она инициализируется
  alert(str);         // А здесь она имеет ожидаемое значение – "локальная"
}

Тоже самое касается и глобальной области видимости, переменная объявленная снизу, доступна наверху:

alert(num);     // undefined
var num = 10;
alert(num);     // 10
Копирование материалов с данного сайта возможно только с разрешения администрации сайта
и при указании прямой активной ссылки на источник.
2011-2018 © puzzleweb.ru

Реклама на сайте | puzinfo@puzzleweb.ru