Какова область видимости переменных в JavaScript? - PullRequest
1889 голосов
/ 01 февраля 2009

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

Ответы [ 24 ]

9 голосов
/ 30 марта 2016

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

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

image

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

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

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

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

9 голосов
/ 22 сентября 2014

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

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

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

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

Цепочка прицела ->

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

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

8 голосов
/ 18 октября 2014

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

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 голосов
/ 24 июня 2014

Глобальная область действия:

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

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

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

6 голосов
/ 29 октября 2015

ПОЧТИ существует только два типа областей 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, за исключением:

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

Таким образом, вы можете увидеть, что 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);

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

5 голосов
/ 26 сентября 2017

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

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

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

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

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

4 голосов
/ 11 июля 2015

В 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 голосов
/ 10 августа 2013

Попробуйте этот любопытный пример. В приведенном ниже примере, если бы 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 голосов
/ 17 сентября 2017

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

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

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

2 голосов
/ 01 ноября 2017

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

  • Локальный охват
  • Глобальный охват

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

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

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

class {

    var carName = " Volvo";

    // code here can use carName

    function myFunction() {
        alert(carName);
        // code here can use carName 
    }
}
...