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

1742

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

Показать ещё 1 комментарий
Теги:
scope
function
variables
var

25 ответов

2178
Лучший ответ

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

  • 270
    Даже близко не быть исчерпывающим, но это, возможно, необходимый набор приемов Javascript, которые необходимы для того, чтобы эффективно ПРОЧИТАТЬ современный Javascript.
  • 0
    Учитывая ваше замечание о «ранжировании», я думаю, я начну читать больше о подобных вещах. Но это не так плохо, как я думал, я достаточно хорошо понял логику, стоящую за этим. Хотя, что касается свойств объекта, если я объявлю его глобально, на него будет ссылаться object.prototype?
Показать ещё 21 комментарий
232

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

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

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

  • 1
    Цепочки контекста - это еще один термин для замыканий [памяти] ... для тех, кто читает здесь, чтобы узнать / войти в javascript.
91

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

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

  • 7
    Я боюсь даже начать отвечать на этот вопрос. Как настоящий программист Javascript, я знаю, как быстро ответ может выйти из-под контроля. Хорошие статьи.
  • 10
    @Triptych: Я знаю, что ты имеешь в виду, когда дела выходят из-под контроля, но, пожалуйста, добавь ответ в любом случае. Я получил выше всего делать несколько запросов ... ответ написан кем - то с фактическим опытом обязательно будет лучше. Пожалуйста, исправьте любой мой ответ, который, безусловно, неверен!
Показать ещё 1 комментарий
57

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

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

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

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


Современный 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 server- ( Node.js), вы можете безопасно использовать оператор let.

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

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

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

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

Изображение 2102


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

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


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

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

  • 2
    «НЕизвестно» вводит в заблуждение, потому что переменная объявлена там из-за подъема.
  • 0
    Приведенный выше пример вводит в заблуждение, переменные «i» и «j» не известны за пределами блока. Переменные 'let' имеют область видимости только в этом конкретном блоке, а не за его пределами. Пусть let имеет и другие преимущества, вы не можете повторно объявить переменную снова, и она содержит лексическую область видимости.
Показать ещё 5 комментариев
36

Вот пример:

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

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

27

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

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

23

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

 var a = 4;
 let (a = 3) {
   alert(a); // 3
 }
 alert(a);   // 4
  • 2
    Да, но безопасно ли это использовать? Я имею в виду, я бы реально выбрал эту реализацию, если мой код будет работать в WebKit?
  • 10
    @Python: Нет, WebKit не поддерживает let .
Показать ещё 5 комментариев
18

Идея определения области 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, и это значение, на которое ссылается предупреждение при вызове.

Изображение 2103

16

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 в отношении имен, импортированных из объекта! Немного хедз-ап на имя, которое уже определено, сделало бы это намного безопаснее. Из-за этого лично я никогда не буду использовать.

  • 0
    У вас есть некоторые ошибки здесь, для одного JavaScript есть формы блочной видимости.
  • 0
    Мои уши (глаза) открыты, Бенджамин. Мои высказанные выше заявления относятся к тому, как я лечу Javascript, но они не основаны на чтении спецификации. И я надеюсь, что вы не имеете в виду оператор with (который является формой видимости объекта) или специальный синтаксис Mozilla 'let'.
Показать ещё 5 комментариев
9

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

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

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

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

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

  • 1
    У меня не работает Firefox 26. Я вставляю код или загружаю файл, нажимаю «Выполнить», и ничего не происходит.
8

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

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

Изображение 2104

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

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

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

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

8

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

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

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

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

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

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

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

  • 1
    Не уверен, почему это не принятый ответ. На самом деле это просто функциональная область (до ECMA6 не было «локальной области») и глобальные привязки
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);
7

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

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

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

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

5

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

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

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

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

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

5

В 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);

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

4

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

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);
3

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

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

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

3

Попробуйте этот любопытный пример. В приведенном ниже примере, если 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());
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 
    }
}
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

В 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

В 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
    }
    
-4

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

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

  • 1
    вы должны быть более информативным

Ещё вопросы

Сообщество Overcoder
Наверх
Меню