Какова область видимости переменных в JavaScript?

Какова область видимости переменных в javascript? Имеют ли они одну и ту же область внутри, а не вне функции? Или это даже имеет значение? Кроме того, где хранятся переменные, если они определены глобально?

+1850
источник поделиться
26 ответов

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

  1. Переменная с глобальным охватом

    // global scope
    var a = 1;
    
    function one() {
      alert(a); // alerts '1'
    }
    
  2. Локальная область

    // global scope
    var a = 1;
    
    function two(a) { // passing (a) makes it local scope
      alert(a); // alerts the given argument, not the global value of '1'
    }
    
    // local scope again
    function three() {
      var a = 3;
      alert(a); // alerts '3'
    }
    
  3. Промежуточное: в JavaScript нет такой вещи, как область блока (ES5; ES6 вводит let)

    а.

    var a = 1;
    
    function four() {
      if (true) {
        var a = 4;
      }
    
      alert(a); // alerts '4', not the global value of '1'
    }
    

    б.

    var a = 1;
    
    function one() {
      if (true) {
        let a = 4;
      }
    
      alert(a); // alerts '1' because the 'let' keyword uses block scoping
    }
    
  4. Промежуточное: свойства объекта

    var a = 1;
    
    function Five() {
      this.a = 5;
    }
    
    alert(new Five().a); // alerts '5'
    
  5. Дополнительно: Закрытие

    var a = 1;
    
    var six = (function() {
      var a = 6;
    
      return function() {
        // JavaScript "closure" means I have access to 'a' in here,
        // because it is defined in the function in which I was defined.
        alert(a); // alerts '6'
      };
    })();
    
  6. Дополнительно: разрешение на основе прототипа

    var a = 1;
    
    function seven() {
      this.a = 7;
    }
    
    // [object].prototype.property loses to
    // [object].property in the lookup chain. For example...
    
    // Won't get reached, because 'a' is set in the constructor above.
    seven.prototype.a = -1;
    
    // Will get reached, even though 'b' is NOT set in the constructor.
    seven.prototype.b = 8;
    
    alert(new seven().a); // alerts '7'
    alert(new seven().b); // alerts '8'
    

  7. Global + Local: дополнительный сложный случай

    var x = 5;
    
    (function () {
        console.log(x);
        var x = 10;
        console.log(x); 
    })();
    

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

    var x = 5;
    
    (function () {
        var x;
        console.log(x);
        x = 10;
        console.log(x); 
    })();
    
  8. Переменная Catch

    var e = 5;
    console.log(e);
    try {
        throw 6;
    } catch (e) {
        console.log(e);
    }
    console.log(e);
    

    Это напечатает 5, 6, 5. Внутри объекта catch e тени глобальных и локальных переменных. Но этот специальный масштаб предназначен только для пойманной переменной. Если вы пишете var f; внутри предложения catch, то это точно так же, как если бы вы определили его до или после блока try-catch.

+2385
источник

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

Элемент в цепочке областей видимости - это в основном Map с указателем на его родительскую область.

При разрешении переменной javascript запускается во внутренней области и ищет наружу.

+231
источник
другие ответы

Связанные вопросы


Похожие вопросы

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

(Я уверен, что есть много тонкостей, которые могут быть описаны в других ответах программистами реального JavaScript. В частности, я встретил эту страницу о том, что именно означает this в любое время. Надеюсь, эта более вводная ссылка достаточно, чтобы вы начали работать.)

+104
источник

Старая школа JavaScript

Традиционно JavaScript имеет только два типа области видимости:

  1. Глобальная область: переменные известны во всем приложении с самого начала приложения (*)
  2. Функциональная область: переменные известны в функции, в которой они объявлены, с начала функции (*)

Я не буду подробно останавливаться на этом, поскольку уже есть много других ответов, объясняющих разницу.


Современный JavaScript

Самые последние спецификации JavaScript теперь также допускают третью область:

  1. Область действия блока: переменные известны в блоке, в котором они объявлены, с момента их объявления (**)

Как создать переменные области видимости блока?

Традиционно вы создаете свои переменные следующим образом:

var myVariable = "Some text";

Переменные области видимости блока создаются следующим образом:

let myVariable = "Some text";

Так в чем же разница между функциональной областью и областью блока?

Чтобы понять разницу между функциональной областью и областью блока, рассмотрите следующий код:

// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here

function loop(arr) {
    // i IS known here, but undefined
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( var i = 0; i < arr.length; i++ ) {
        // i IS known here, and has a value
        // j IS NOT known here
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here

    for( let j = 0; j < arr.length; j++ ) {
        // i IS known here, and has a value
        // j IS known here, and has a value
        // k IS known here, but has a value only the second time loop is called
        // l IS NOT known here
    };

    // i IS known here, and has a value
    // j IS NOT known here
    // k IS known here, but has a value only the second time loop is called
    // l IS NOT known here
}

loop([1,2,3,4]);

for( var k = 0; k < arr.length; k++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS NOT known here
};

for( let l = 0; l < arr.length; l++ ) {
    // i IS NOT known here
    // j IS NOT known here
    // k IS known here, and has a value
    // l IS known here, and has a value
};

loop([1,2,3,4]);

// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here

Здесь мы видим, что наша переменная j известна только в первом цикле for, но не до и после. Тем не менее, наша переменная i известна во всей функции.

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


Безопасно ли сегодня использовать блочные переменные области видимости?

Насколько это безопасно сегодня или нет, зависит от вашей среды:

  • Если вы пишете код JavaScript на стороне сервера ( Node.js), вы можете смело использовать оператор let.

  • Если вы пишете код JavaScript на стороне клиента и используете браузер (например, Traceur или babel-standalone), вы можете смело использовать оператор let, однако ваш код, вероятно, будет не оптимальным с точки зрения производительности.

  • Если вы пишете код JavaScript на стороне клиента и используете транспортер на основе Node (например, скрипт оболочки traceur или Babel), вы можете смело использовать оператор let. А поскольку ваш браузер будет знать только о переданном коде, недостатки производительности должны быть ограничены.

  • Если вы пишете код JavaScript на стороне клиента и не используете транспортер, вам следует подумать о поддержке браузера.

    Вот некоторые браузеры, которые вообще не поддерживают let:

    • Internet Explorer 10 и ниже
    • Firefox 43 и ниже
    • Safari 9 и ниже
    • Android-браузер 4 и ниже
    • Опера 27 и ниже
    • Chome 40 и ниже
    • ЛЮБАЯ версия Opera Mini и Blackberry Browser

enter image description here


Как отслеживать поддержку браузера

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


(*) Глобальные и функциональные переменные могут быть инициализированы и использованы до того, как объявлены, потому что переменные JavaScript подняты. Это означает, что объявления всегда находятся на вершине области видимости.

(**) Переменные области видимости не подняты

+68
источник

Вот пример:

<script>

var globalVariable = 7; //==window.globalVariable

function aGlobal( param ) { //==window.aGlobal(); 
                            //param is only accessible in this function
  var scopedToFunction = {
    //can't be accessed outside of this function

    nested : 3 //accessible by: scopedToFunction.nested
  };

  anotherGlobal = {
    //global because there no `var`
  }; 

}

</script>

Вам нужно исследовать закрытие и использовать их для создания частных членов.

+38
источник

Ключ, как я понимаю, состоит в том, что Javascript имеет область видимости уровня и более общую область C-области.

Вот хорошая статья по этой теме.

+31
источник

В "Javascript 1.7" (расширение Mozilla для Javascript) можно также объявить переменные объемной области с помощью let statement:

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4
+26
источник

Идея определения области JavaScript, когда она была первоначально разработана Brendan Eich, взята из HyperCard скриптов язык HyperTalk.

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

Именно так разработана система обзора JavaScript. У него просто разные имена. Карты в JavaScript известны как Контексты выполнения ECMA. Каждый из этих контекстов содержит три основные части. Переменная среда, лексическая среда и эта привязка. Возвращаясь к ссылке на карты, лексическая среда содержит весь контент из предыдущих карт ниже в стеке. Текущий контекст находится в верхней части стека, и любое содержимое, объявленное там, будет храниться в переменной среде. Переменная среда будет иметь приоритет в случае именования столкновений.

Эта привязка укажет на содержащий объект. Иногда контексты или контексты выполнения изменяются без изменения объекта-объекта, например, в объявленной функции, где содержащий объект может быть window или конструктор.

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

Итак, это техническое объяснение. На практике важно помнить, что в JavaScript

  • Области являются технически "Контекстами выполнения"
  • Контексты образуют стек сред, в котором хранятся переменные
  • Верхняя часть стека имеет приоритет (нижний - глобальный контекст)
  • Каждая функция создает контекст выполнения (но не всегда новую привязку)

Применяя это к одному из предыдущих примеров (5. "Закрытие" ) на этой странице, можно следить за стеком контекстов выполнения. В этом примере в стеке есть три контекста. Они определяются внешним контекстом, контекстом в вызываемой немедленно функции, вызванной var six, и контекстом в возвращаемой функции внутри функции var six, вызываемой сразу.

i) Внешний контекст. Он имеет переменную среду a = 1
 ii) В контексте IIFE он имеет лексическую среду a = 1, но переменную среду a = 6, которая имеет приоритет в стеке  iii) Возвращенный контекст функции, он имеет лексическую среду a = 6, и это значение, на которое ссылается предупреждение при вызове.

введите здесь описание изображения

+22
источник

1) Существует глобальная область видимости, область действия и области поиска и захвата. В переменной для уровня не существует области уровня "block". Операторы with и catch выводят имена в свои блоки.

2) Области привязаны к функциям вплоть до глобальной области.

3) Свойства разрешаются путем прохождения цепи прототипа. Оператор with присваивает имена свойств объекта в лексическую область, определенную блоком с.

РЕДАКТИРОВАТЬ: ECMAAScript 6 (Harmony) предлагается поддерживать let, и я знаю, что chrome позволяет флаг "гармонии", поэтому, возможно, он поддерживает его.

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

РЕДАКТИРОВАТЬ: Основываясь на том, что Бенджамин указал на комментарии и комментарии в комментариях, я отредактировал сообщение и добавил больше. Оба оператора with и catch задают переменные в своих соответствующих блоках, и это область блоков. Эти переменные являются псевдонимом свойств объектов, переданных в них.

 //chrome (v8)

 var a = { 'test1':'test1val' }
 test1   // error not defined
 with (a) { var test1 = 'replaced' }
 test1   // undefined
 a       // a.test1 = 'replaced'

EDIT: Пример разъяснения:

test1 привязан к блоку с, но сглажен к a.test1. "Var test1" создает новую переменную test1 в верхнем лексическом контексте (функции или глобальном), если только он не является свойством a, которое оно есть.

Хлоп! Будьте осторожны, используя 'with' - так же, как var является noop, если переменная уже определена в функции, она также является noop в отношении имен, импортированных из объекта! Немного хедз-ап на имя, которое уже определено, сделало бы это намного безопаснее. Из-за этого лично я никогда не буду использовать.

+17
источник

Я обнаружил, что многие люди, не знакомые с JavaScript, не понимают, что наследование доступно по умолчанию на языке, а область возможностей - единственная область действия. Я предоставил расширение для beautifier, который я написал в конце прошлого года под названием JSPretty. Функция цветовой функции функции в коде и всегда связывает цвет для всех переменных, объявленных в этой области. Закрытие визуально демонстрируется, когда переменная с цветом из одной области видимости используется в другой области.

Попробуйте воспользоваться функцией:

См. демонстрацию по адресу:

Просмотрите код по адресу:

В настоящее время эта функция предлагает поддержку глубины 16 вложенных функций, но в настоящее время не цветные глобальные переменные.

+10
источник

JavaScript имеет только два типа области:

  • Глобальный масштаб. Глобальный - это не что иное, как область уровня окна. Здесь переменная присутствует во всем приложении.
  • Функциональная область. Переменная, объявленная внутри функции с ключевым словом var, имеет функциональную область.

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

        a = "global";
         function outer(){ 
              b = "local";
              console.log(a+b); //"globallocal"
         }
outer();

Цепочка области →

  • Уровень окна - a и outer функции находятся на верхнем уровне в цепочке областей видимости.
  • когда внешняя функция, называемая новой variable scope object (и включаемой в цепочку областей), добавлена ​​с переменной b внутри нее.

Теперь, когда переменная a потребовала, чтобы она сначала выполняла поиск ближайшей области переменных, и если переменная не существует, то она перемещается в следующий объект цепочки переменных переменной. В этом случае это уровень окна.

+9
источник

Чтобы добавить к другим ответам, область видимости - это список всех объявленных идентификаторов (переменных) и применяется строгий набор правил относительно того, как они доступны для текущего кода. Этот поиск может быть предназначен для назначения переменной, которая является ссылкой LHS (левая сторона), или может быть использована для извлечения ее значения, которое является ссылкой RHS (справа). Эти образы - это то, что движок JavaScript делает внутренне, когда он компилирует и выполняет код.

Итак, с этой точки зрения, я думаю, что картина поможет, что я нашел в книге Scopes and Closures Kyle Simpson:

image

Цитата из его книги:

Здание представляет собой наш набор правил вложенных областей. Первый этаж здания представляет собой ваш текущий объем выполнения, где бы ты ни был. Верхний уровень здания - глобальный масштаб. Вы разрешаете ссылки LHS и RHS, просматривая текущий этаж, и если вы не найдете его, поднявшись на лифте на следующий этаж, глядя туда, затем на следующий и т.д. Как только вы доберетесь до верхнего этажа (глобальная область), вы либо находите то, что ищете, либо вы не делают. Но вы должны остановиться независимо.

Одно замечание, которое стоит упомянуть, "Смещение поиска останавливается, когда оно находит первое совпадение".

Эта идея "уровней видимости" объясняет, почему "this" можно изменить с помощью вновь созданной области, если она просматривается во вложенной функции. Вот ссылка, которая затрагивает все эти детали, Все, что вы хотели знать о области javascript

+9
источник

Глобальный масштаб:

Глобальные переменные в точности похожи на глобальные звезды (Джеки Чан, Нельсон Мандела). Вы можете получить к ним доступ (получить или установить значение) из любой части вашего приложения. Глобальные функции похожи на глобальные события (Новый год, Рождество). Вы можете выполнять (вызывать) их из любой части вашего приложения.

//global variable
var a = 2;

//global function
function b(){
   console.log(a);  //access global variable
}

Локальная область:

Если вы находитесь в США, вы можете узнать Ким Кардашян, печально известную знаменитость (ей как-то удается сделать таблоиды). Но люди за пределами США не узнают ее. Она местная звезда, привязанная к своей территории.

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

function b(){
   var d = 21; //local variable
   console.log(d);

   function dog(){  console.log(a); }
     dog(); //execute local function
}

 console.log(d); //ReferenceError: dddddd is not defined    

Проверьте эту статью для углубленного понимания сферы применения

+8
источник

запустите код. надеюсь, что это даст представление о области охвата

Name = 'global data';
document.Name = 'current document data';
(function(window,document){
var Name = 'local data';
var myObj = {
    Name: 'object data',
    f: function(){
        alert(this.Name);
    }
};

myObj.newFun = function(){
    alert(this.Name);
}

function testFun(){
    alert("Window Scope : " + window.Name + 
          "\nLocal Scope : " + Name + 
          "\nObject Scope : " + this.Name + 
          "\nCurrent document Scope : " + document.Name
         );
}


testFun.call(myObj);
})(window,document);
+8
источник

В ALMOST есть только два типа областей JavaScript:

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

Таким образом, любые блоки, отличные от функций, не создают новую область. Это объясняет, почему for-loops перезаписывают внешние облачные переменные:

var i = 10, v = 10;
for (var i = 0; i < 5; i++) { var v = 5; }
console.log(i, v);
// output 5 5

Вместо этого используйте функции:

var i = 10, v = 10;
$.each([0, 1, 2, 3, 4], function(i) { var v = 5; });
console.log(i,v);
// output 10 10

В первом примере не было области блока, поэтому первоначально объявленные переменные были перезаписаны. Во втором примере из-за функции появилась новая область, поэтому первоначально объявленные переменные были SHADOWED, а не перезаписаны.

Это почти все, что вам нужно знать с точки зрения JavaScript, за исключением:

  • try/catch вводит новую область ТОЛЬКО для самой переменной исключения, другие переменные не имеют новой области
  • with-clause - это, по-видимому, другое исключение, но с использованием предложения с его предложением очень не рекомендуется (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with)

Таким образом, вы можете видеть, что область обзора JavaScript на самом деле чрезвычайно проста, хотя и не всегда интуитивная. Несколько вещей, о которых нужно знать:

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

Итак, этот код:

var i = 1;
function abc() {
  i = 2;
  var i = 3;
}
console.log(i);     // outputs 1

эквивалентно:

var i = 1;
function abc() {
  var i;     // var declaration moved to the top of the scope
  i = 2;
  i = 3;     // the assignment stays where it is
}
console.log(i);

Это может показаться противоречивым, но это имеет смысл с точки зрения императивного разработчика языка.

+6
источник

Современные Js, ES6 +, ' const' и ' let'

Для каждой создаваемой переменной вы должны использовать область обзора, как и большинство других основных языков. var является устаревшим. Это делает ваш код более безопасным и более ремонтопригодным.

const следует использовать для 95% случаев. Это делает так, чтобы переменная reference не могла измениться. Свойства массива, объекта и DOM node могут меняться и, вероятно, должны быть const.

let следует использовать для любой переменной, ожидающей переназначения. Это включает в себя цикл for. Если вы изменили значение за пределами инициализации, используйте let.

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

+5
источник

В JS есть только области функций. Не блокируйте области! Вы также можете увидеть, что такое подъем.

var global_variable = "global_variable";
var hoisting_variable = "global_hoist";

// Global variables printed
console.log("global_scope: - global_variable: " + global_variable);
console.log("global_scope: - hoisting_variable: " + hoisting_variable);

if (true) {
    // The variable block will be global, on true condition.
    var block = "block";
}
console.log("global_scope: - block: " + block);

function local_function() {
    var local_variable = "local_variable";
    console.log("local_scope: - local_variable: " + local_variable);
    console.log("local_scope: - global_variable: " + global_variable);
    console.log("local_scope: - block: " + block);
    // The hoisting_variable is undefined at the moment.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);

    var hoisting_variable = "local_hoist";
    // The hoisting_variable is now set as a local one.
    console.log("local_scope: - hoisting_variable: " + hoisting_variable);
}

local_function();

// No variable in a separate function is visible into the global scope.
console.log("global_scope: - local_variable: " + local_variable);
+4
источник

Каждый фрагмент кода JavaScript (глобальный код или функции) имеет связанную с ним цепочку областей видимости. Этот объем chain - это список или цепочка объектов, которые определяют переменные, которые являются "в области" для этого код. Когда JavaScript нужно искать значение переменной x (процесс, называемый переменное разрешение), он начинается с просмотра первого объекта в цепочке. Если этот объект имеет свойство с именем x, используется значение этого свойства. Если первый объект не имеет свойство с именем x, JavaScript продолжает поиск со следующим объектом в цепочке. Если второй объект не имеет свойства с именем x, поиск переходит к следующему объект и т.д. Если x не является свойством ни одного из объектов в цепочке областей видимости, тогда x не подходит для этого кода, и возникает ссылка ReferenceError. В коде JavaScript верхнего уровня (т.е. Код, не содержащийся в каких-либо определениях функций) цепочка областей видимости состоит из одного объекта, глобального объекта. В не-вложенной функции, цепочка областей видимости состоит из двух объектов. Первый - это объект, который определяет функции параметры и локальные переменные, а второй - глобальный объект. Во вложенной функции, цепочка областей действия имеет три или более объектов. Важно понять, как эта цепочка объектов. Когда функция DEFINED, она сохраняет действующую цепочку областей действия. Когда эта функция INVOKED, она создает новый объект для хранения своих локальных переменных и добавляет, что новый объект к цепочке хранимых цепей создает новую, более длинную цепочку, которая представляет область действия для вызова этой функции. Это становится более интересным для вложенные функции, поскольку каждый раз, когда вызывается внешняя функция, внутренняя функция снова определено. Поскольку цепочка областей действия различается при каждом вызове внешней функции, внутренняя функция будет тонко различной при каждом ее определении - код внутреннего функция будет одинаковой при каждом вызове внешней функции, но цепочка областей видимости связанные с этим кодом будут отличаться. Это понятие цепи видимости имеет решающее значение для понимания закрытий.

+4
источник

Попробуйте этот любопытный пример. В приведенном ниже примере, если a было числовым, инициализированным в 0, вы увидите 0, а затем 1. За исключением того, что a - объект, а javascript передает f1 указатель на не его копию. В результате вы получаете одинаковое предупреждение одновременно.

var a = new Date();
function f1(b)
{
    b.setDate(b.getDate()+1);
    alert(b.getDate());
}
f1(a);
alert(a.getDate());
+3
источник

Я понимаю, что существует 3 области: глобальная область действия, доступная во всем мире; локальная область действия, доступная для целой функции независимо от блоков; и область блока, доступная только для блока, оператора или выражения, на котором оно было использовано. Глобальная и локальная область обозначаются ключевым словом "var", либо внутри функции, либо снаружи, а область блока указывается ключевым словом "let".

Для тех, кто считает, что существует только глобальная и локальная область, объясните, почему Mozilla будет иметь всю страницу, описывающую нюансы области блока в JS.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

+3
источник

В JavaScript есть два типа области действия:

  • Локальная область
  • Глобальная область

Функция "Ниже" имеет локальную переменную области carName. И эта переменная недоступна из-за пределов функции.

function myFunction() {
    var carName = "Volvo";
    alert(carName);
    // code here can use carName
}

В классе ниже есть глобальная переменная области carName. И эта переменная доступна извне в классе.

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}
+2
источник

В EcmaScript5 есть в основном две области: локальная область и глобальная область, но в EcmaScript6 мы имеем в основном три области, локальную область действия, глобальную область действия и новую область, называемую область блока.

Пример области блока: -

for ( let i = 0; i < 10; i++)
{
 statement1...
statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined.
}
+1
источник

В ECMAScript 6 введены слова let и const. Эти ключевые слова можно использовать вместо ключевого слова var. В отличие от ключевого слова var ключевые слова let и const поддерживают декларацию локальной области внутри операторов блока.

var x = 10
let y = 10
const z = 10
{
  x = 20
  let y = 20
  const z = 20
  {
    x = 30
    // x is in the global scope because of the 'var' keyword
    let y = 30
    // y is in the local scope because of the 'let' keyword
    const z = 30
    // z is in the local scope because of the 'const' keyword
    console.log(x) // 30
    console.log(y) // 30
    console.log(z) // 30
  }
  console.log(x) // 30
  console.log(y) // 20
  console.log(z) // 20
}

console.log(x) // 30
console.log(y) // 10
console.log(z) // 10
+1
источник

ES5 и более ранние:

Переменные в Javascript изначально (до ES6) были ES6 лексической функцией. Термин лексически ограниченный означает, что вы можете увидеть область действия переменных, "посмотрев" на код.

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

  1. Когда функция ищет разрешение переменной, она сначала смотрит на свою область видимости. Это тело функции, т.е. Все, что находится в фигурных скобках {} (за исключением переменных внутри других функций, находящихся в этой области видимости).
  2. Если он не может найти переменную внутри тела функции, он поднимется до цепочки и рассмотрит область действия переменной в функции, в которой была определена функция. Это то, что подразумевается под лексической областью действия, мы можем видеть в коде, где была определена эта функция, и, таким образом, можно определить цепочку области действия, просто взглянув на код.

Пример:

// global scope
var foo = 'global';
var bar = 'global';
var foobar = 'global';

function outerFunc () {
 // outerFunc scope
 var foo = 'outerFunc';
 var foobar = 'outerFunc';
 innerFunc();
 
 function innerFunc(){
 // innerFunc scope
  var foo = 'innerFunc';
  console.log(foo);
  console.log(bar);
  console.log(foobar);
  }
}

outerFunc();

Что происходит, когда мы пытаемся foobar в консоль переменные foo, bar и foobar:

  1. Мы пытаемся войти в консоль foo, foo можно найти внутри самой функции innerFunc. Следовательно, значение foo разрешается в строку innerFunc.
  2. Мы пытаемся войти в панель bar, консоль не может быть найдена внутри самой функции innerFunc. Поэтому нам нужно подняться по цепочке прицелов. Сначала мы посмотрим на внешнюю функцию, в которой была определена функция innerFunc. Это функция outerFunc. В области outerFunc мы можем найти переменную bar, которая содержит строку "externalFunc".
  3. foobar не может быть найден во innerFunc. , Поэтому нам нужно подняться по цепочке областей видимости в область видимости innerFunc. Это также не может быть найдено здесь, мы поднимаемся на другой уровень к глобальной области видимости (то есть к самой внешней области видимости). Здесь мы находим переменную foobar, которая содержит строку "global". Если он не найдет переменную после перехода по цепочке областей видимости, механизм JS выдаст referenceError.

ES6 (ES 2015) и старше:

Те же самые понятия лексического объема и области видимости все еще применяются в ES6. Однако были введены новые способы объявления переменных. Есть следующее:

  • let: создает переменную области видимости блока
  • const: создает переменную области блока, которая должна быть инициализирована и не может быть переназначена

Самое большое различие между var и let/const состоит в том, что var является областью действия функции, тогда как let/const является областью действия блока. Вот пример, чтобы проиллюстрировать это:

let letVar = 'global';
var varVar = 'global';

function foo () {
  
  if (true) {
    // this variable declared with let is scoped to the if block, block scoped
    let letVar = 5;
    // this variable declared with let is scoped to the function block, function scoped
    var varVar = 10;
  }
  
  console.log(letVar);
  console.log(varVar);
}


foo();

В приведенном выше примере letVar записывает глобальное значение, потому что переменные, объявленные с помощью let имеют область видимости. Они перестают существовать вне соответствующего блока, поэтому к переменной нельзя получить доступ вне блока if.

+1
источник

В JavaScript есть два типа областей.

  • Глобальная область: переменная, объявленная в глобальной области, может быть использована в любом месте программы очень плавно. Например:

    var carName = " BMW";
    
    // code here can use carName
    
    function myFunction() {
         // code here can use carName 
    }
    
  • Функциональная область или локальная область: переменная, объявленная в этой области, может использоваться только в своей собственной функции. Например:

    // code here can not use carName
    function myFunction() {
       var carName = "BMW";
       // code here can use carName
    }
    
-2
источник

Global: переменная, объявленная вне функции

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

-3
источник

Посмотрите другие вопросы по меткам или Задайте вопрос