Цепь областей видимости в JavaScript


Я читаю scope chain в Javascript, но это не имеет никакого смысла для меня, может ли кто-нибудь сказать мне, что такое scope chain и как она работает с графикой или что-то даже идиот может понять. Я googled его, но я не нашел что-то понятное :(

спасибо заранее.

6 51

6 ответов:

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

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

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

Рассмотрим пример с тремя вложенными функции:

var currentScope = 0; // global scope
(function () {
  var currentScope = 1, one = 'scope1';
  alert(currentScope);
  (function () {
    var currentScope = 2, two = 'scope2';
    alert(currentScope);
    (function () {
      var currentScope = 3, three = 'scope3';
      alert(currentScope);
      alert(one + two + three); // climb up the scope chain to get one and two
    }());
  }());
}());

рекомендуется читает:

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

function foo() {
    alert(this===window)
}

будет предупреждать true, потому что окно является объектом, который владеет методом "foo". Любые переменные, определенные в функции, становятся доступными через уникальную цепочку областей действия этой функции, окружающая среда.

function world() {
    var name = 'global';
    alert(name)
}

будет предупреждать "глобальный", очевидно.

function world() {
    var name = 'global';
    (function() {
        var name = 'country';
        alert(name)
    })();
    alert(name)
}

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

во втором вызове оповещения,name также определяется в том же контексте и предупреждает "глобальный";

function world() {
    var name = 'global';
    (function() { alert(name) })();
}

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

ссылки:

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

function get_inner_scope () {
    var outer = 'Outer variable value';
    return function () {
        alert(outer);
    }
}
f = get_inner_scope();
f(); // alerts Outer variable value

более deatailed информация с другими образцами по первой ссылке google: http://blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx

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

var currentScope = 0; // global scope
function a () {
   var currentScope = 1, one = 'scope1';
   alert(currentScope);

  function b () {
      var currentScope = 2, two = 'scope2';
      alert(currentScope);

      function c () {
         var currentScope = 3, three = 'scope3';
         alert(currentScope);
  alert(one + two + three); // climb up the scope chain to get one and two
     }
     c();
  }
  b();
}
a();

цепь областей видимости в JavaScript объяснить с точки зрения обывателя

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

позже он понимает, что завтра последний день, чтобы заплатить за учебу дочери 1000$.
Он бежит домой,находит свои сбережения в 400$, беспокоится об остальном(600$).Мгновенная мысль, которая вспыхивает, состоит в том, чтобы заимствовать некоторые из его отца Мэтью.
Мэтью, бедный плотник, лишенный из любых денег продает свой унаследованный браслет за 300$ и одалживает его сыну Алексу.
Алекс, имеющий хорошую репутацию в обществе, получает оставшиеся 300$ от местного банка немедленно и оплачивает обучение своей дочери вовремя.

возвращаясь к цепочке областей в Javascript:
Alex-функция в javascript
Мэтью-непосредственная функция, в которую вложен Алекс.
Mathews parents-непосредственная функция, в которую вложен Mathew.
Банк-Глобальный переменная.

function Bank() {
    loan=300;
    Mathew();

    function Mathew() {
        mathew=300;
        Alex();

        function Alex() {
            savings:400;
            alert('I need some money');
        }

    }

}

Bank();

область действия цепочки Алекса на данный момент выглядит так: [сбережения: 400]+[Мэтью: 300]+[ссуда:300];

резюме:

цепочка областей используется для разрешения значения имен переменных в javascript. Без цепочки областей движок Javascript не знал бы, какое значение выбрать для определенного имени переменной, если есть несколько определенных в разных областях. Цепочка областей в javascript - это лексически определены, что означает, что мы можем видеть, что цепочка областей будет, глядя на код.

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

затем, когда функции выполняются функции требует значение для обеих переменных foo и bar. Значение foo может быть разрешено на уровне innerTestFunc и 10 для обоих. 10 уже найдено в innerFoo, так что не нужно подниматься на цепь области для foo.

в случае bar переменной функция не может найти его в innerFoo. Поэтому он будет подниматься вверх по цепочке прицела. Он сначала встречает переменную bar функции test, поэтому он будет решать стоимостью bar к любому значению в тестовой функции (5, 20 в нашем примере).