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

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

вопрос задан 1.02.2009
lYriCAlsSH
22732 репутация

26 ответов


  • 2295 рейтинг

    Я думаю, что лучшее, что я могу сделать, это дать вам кучу примеров для изучения. Программисты 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. Advanced : Разрешение на основе прототипа

      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 : Дополнительный комплекс Case

      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-scoped

      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.

    ответ дан Triptych, с репутацией 148679, 1.02.2009
  • 222 рейтинг

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

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

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

    ответ дан krosenvold, с репутацией 51204, 1.02.2009
  • 96 рейтинг

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

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

    ответ дан Jon Skeet, с репутацией 1057123, 1.02.2009
  • 57 рейтинг

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

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

    1. Global Scope : Переменные известны в приложении с самого начала приложения (*)
    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 на стороне сервера ( Узел. js ), вы можете смело использовать инструкцию let.

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

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

      Сегодня, 23 февраля 2016 г., это некоторые браузеры, которые либо не поддерживают let, либо имеют только частичную поддержку:

      • Internet Explorer 10 и ниже (без поддержки)
      • Firefox 43 и ниже (без поддержки)
      • Safari 9 и ниже (без поддержки)
      • Opera Mini 8 и ниже (без поддержки)
      • Android-браузер 4 и ниже (без поддержки)
      • Opera 36 и ниже (частичная поддержка)
      • Chome 51 и ниже (частичная поддержка)

    enter image description here


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

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


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

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

    ответ дан John Slegers, с репутацией 26343, 23.02.2016
  • 35 рейтинг

    Вот пример:

    
    
    

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

    ответ дан geowa4, с репутацией 26578, 1.02.2009
  • 28 рейтинг

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

    Вот хорошая статья на эту тему.

    ответ дан James McMahon, с репутацией 29155, 15.05.2012
  • 23 рейтинг

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

     var a = 4;
     let (a = 3) {
       alert(a); // 3
     }
     alert(a);   // 4
    
    ответ дан kennytm, с репутацией 392915, 6.04.2010
  • 18 рейтинг

    Идея определения объема в JavaScript, изначально разработанная Бренданом Айхом , возникла из языка сценариев 3450687280 HyperCard HyperTalk .

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

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

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

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

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

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

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

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

    enter image description here

    ответ дан Travis J, с репутацией 62550, 14.09.2015
  • 16 рейтинг

    1) Существует глобальная область действия, область действия функции, а также области действия with и catch. В общем случае для переменных нет области уровня «блок» - операторы with и catch добавляют имена к своим блокам.

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

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

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

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

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

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

    РЕДАКТИРОВАТЬ: Уточняющий пример:

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

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

    ответ дан Gerard ONeill, с репутацией 2236, 25.10.2013
  • 9 рейтинг

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

    Попробуйте функцию по адресу:

    Посмотреть демонстрацию по адресу:

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

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

    ответ дан austincheney, с репутацией 1129, 21.03.2013
  • 8 рейтинг

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

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

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

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

    Цепочка прицела - & gt;

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

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

    ответ дан Anshul, с репутацией 5871, 21.09.2014
  • 8 рейтинг

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

    Итак, с этой точки зрения, я думаю, что поможет картина, которую я нашел в электронной книге «Области применения и замыкания» Кайла Симпсона:

    image

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

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

    Стоит упомянуть одну вещь: «Поиск области останавливается, когда он находит первое совпадение».

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

    ответ дан James Drinkard, с репутацией 8969, 30.03.2016
  • 7 рейтинг

    Global Scope:

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

    //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    
    

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

    ответ дан KhanSharp, с репутацией 7475, 24.06.2014
  • 7 рейтинг

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

    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);
    
    ответ дан Yeasin Abedin Siam, с репутацией 771, 18.10.2014
  • 5 рейтинг

    Modern Js, ES6 +, «const» и «let»

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

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

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

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

    ответ дан Gibolt, с репутацией 4052, 26.09.2017
  • 5 рейтинг

    ПОЧТИ существует только два типа областей JavaScript:

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

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

    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
    

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

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

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

    • декларации 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);
    

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

    ответ дан jackbean818, с репутацией 122, 29.10.2015
  • 4 рейтинг

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

    ответ дан Fanyo SILIADIN, с репутацией 665, 28.01.2017
  • 4 рейтинг

    В 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);
    
    ответ дан koredalin, с репутацией 408, 11.07.2015
  • 3 рейтинг

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

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

    https: // разработчик. Mozilla. org / en-US / docs / Web / JavaScript / Справочник / Заявления / let

    ответ дан mrmaclean89, с репутацией 226, 16.09.2017
  • 3 рейтинг

    Попробуйте этот любопытный пример. В приведенном ниже примере, если бы число было инициализировано 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());
    
    ответ дан Mig82, с репутацией 31, 10.08.2013
  • 2 рейтинг

    В 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 
        }
    }
    
    ответ дан Abdur Rahman, с репутацией 361, 1.11.2017
  • 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
    
    ответ дан Dava E., с репутацией 118, 9.02.2018
  • 1 рейтинг

    В 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.
    }
    
    ответ дан Vivek Mehta, с репутацией 157, 15.12.2017
  • 0 рейтинг

    ES5 и старше:

    Переменные в Javascript изначально (до 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();

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

    1. Мы пытаемся войти в консоль foo, foo находится внутри самой функции innerFunc. Поэтому значение foo разрешается в строку innerFunc.
    2. Мы пытаемся войти бар в консоль, бар не может быть найден внутри самой функции innerFunc. Поэтому нам нужно подняться по цепочке прицелов . Сначала мы посмотрим на внешнюю функцию, в которой была определена функция innerFunc. Это функция outerFunc. В области outerFunc мы можем найти переменную bar, которая содержит строку «externalFunc».
    3. foobar не может быть найден в 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.

    ответ дан Willem van der Veen, с репутацией 2793, 30.09.2018
  • -2 рейтинг

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

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

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

      // code here can not use carName
      function myFunction() {
         var carName = "BMW";
         // code here can use carName
      }
      
    ответ дан A. Randhawa, с репутацией 55, 30.09.2015
  • -3 рейтинг

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

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

    ответ дан poisonlocc, с репутацией 134, 3.01.2015