JavaScript. Подробное руководство, 6-е издание, стр. 30

3.10. Область видимости переменной

Область видимости (

<b>scope</b>
) переменной - это та часть программы, для которой эта переменная определена. Глобальная переменная имеет глобальную область видимости - она определена для всей JavaScript-программы. В то же время переменные, объявленные внутри функции, определены только в ее теле. Они называются локальными и имеют локальную область видимости. Параметры функций также считаются локальными переменными, определенными только в теле этой функции.

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

<b>var scope = &quot;global&quot;; // Объявление глобальной переменной</b>

<b>function checkscope() { </b>

<b>  var scope = &quot;local&quot;; // Объявление локальной переменной с тем же именем </b>

<b>  return scope; // Вернет локальное значение, а не глобальное</b>

<b>}</b>

<b>checkscope()   // =&gt; &quot;local&quot;</b>

Объявляя переменные с глобальной областью видимости, инструкцию

<b>var</b>
можно опустить, но при объявлении локальных переменных всегда следует использовать инструкцию
<b>var</b>
. Посмотрите, что получается, если этого не сделать:

<b>scope = &quot;global&quot;;// Объявление глобальной переменной, даже без var.</b>

<b>function checkscope2() { </b>

<b>scope = &quot;local&quot;; // Ой! Мы изменили глобальную переменную.</b>

<b>myscope = &quot;local&quot;; // Неявно объявляется новая глоб. переменная.</b>

<b>return [scope, myscope];// Вернуть два значения.</b>

<b>checkscope2() // =&gt; [&quot;local&quot;, &quot;local&quot;]: имеется побочный эффект!</b>

<b>scope // =&gt; &quot;local&quot;: глобальная переменная изменилась.</b>

<b>myscope // =&gt; &quot;local&quot;: нарушен порядок в глобальном пространстве имен.</b>

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

<b>var scope = &quot;global scope&quot;; // Глобальная переменная</b>

<b>function checkscopeO {</b>

<b>  var scope = &quot;local scope”; // Локальная переменная </b>

<b>  function nestedO {</b>

<b>    var scope = &quot;nested scope&quot;; // Вложенная область видимости локальных переменных </b>

<b>    return scope; // Вернет значение этой переменной scope</b>

<b>  }</b>

<b>  return nested();</b>

<b>}</b>

3.10.1. Область видимости функции и подъем

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

В следующем фрагменте переменные i, j и к объявляются в разных местах, но все они имеют одну и ту же область видимости - все три переменные доступны из любого места в теле функции:

<b>function test(o) { </b>

<b>  var і = 0; // і определена в теле всей функции</b>

<b>  if (typeof о == &quot;object&quot;) {</b>

<b>    var j = 0; // j определена везде, не только в блоке</b>

<b>    for(var k=0; k &lt; 10; k++) { // к определена везде, не только в цикле </b>

<b>      console.log(k); // выведет числа от 0 до 9</b>

<b>    }</b>

<b>    console.log(k); // к по-прежнему определена: выведет 10</b>

<b>  }</b>

<b>  console.log(j); // j определена, но может быть неинициализирована</b>

<b>}</b>

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

<b>var scope = &quot;global&quot;;</b>

<b>function f() {</b>

<b>  console.log(scope); // Выведет &quot;undefined&quot;, а не &quot;global&quot;</b>

<b>  var scope = &quot;local&quot;; // Инициализируется здесь, а определена везде</b>

<b>  console.log(scope); // Выведет &quot;local&quot;</b>

<b>}</b>

Можно было бы подумать, что первая инструкция внутри функции должна вывести слово «global», потому что инструкция

<b>var</b>
с объявлением локальной переменной еще не была выполнена. Однако вследствие действия правил области видимости функции выводится совсем другое значение. Локальная переменная определена во всем теле функции, а это означает, что глобальная переменная с тем же именем оказывается скрытой для всей функции. Хотя локальная переменная определена во всем теле функции, она остается неинициализированной до выполнения инструкции
<b>var</b>
. То есть функция выше эквивалентна реализации, приведенной ниже, в которой объявление переменной «поднято» в начало функции, а инициализация переменной выполняется там же, где и раньше: