66

Javascript でスコープ チェーンを読んだことがありますが、意味がわかりませんでした。スコープ チェーンとは何か、それがグラフィックやばかでも理解できるものでどのように機能するかを教えてください。私はそれをグーグルで検索しましたが、わかりやすいものは見つかりませんでした:(

4

6 に答える 6

70

スコープ チェーンを理解するには、クロージャがどのように機能するかを理解する必要があります。

関数をネストすると、クロージャーが形成されます。内部関数は、親関数が既に実行された後でも、外側の囲み関数に存在する変数を参照できます。

JavaScript は、スコープ チェーンをたどってローカルからグローバルに移動することにより、特定のコンテキスト内の識別子を解決します。

3 つのネストされた関数を使用したこの例を考えてみましょう。

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
    }());
  }());
}());

推奨される読み取り:

于 2009-09-27T19:15:44.390 に答える
20

ECMAScript (JS のベースとなるコア言語) で関数を呼び出すと、別の実行コンテキストが生成され、互いに個別に実行されます。各実行コンテキスト内でthis、問題のオブジェクトを参照し、関数がアタッチされているものをデフォルトとします。

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

ウィンドウは 'foo' メソッドを所有するオブジェクトであるため、アラートは true になります。関数で定義されたすべての変数は、その関数の一意のスコープ チェーンである環境を通じてアクセスされます。

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

明らかに「グローバル」に警告します。

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

最新の例では、最初のアラートが呼び出されると、Javascript は内部関数のスコープ チェーンで識別子nameが定義されていると判断するため、それを取得するためにスコープ チェーンを検索する必要はありません。

2 番目のアラート呼び出しでnameも、同じコンテキストで定義され、「グローバル」にアラートが送信されます。

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

この例では、name識別子は同じコンテキストで定義されていないため、名前が定義されている外側の関数までスコープ チェーンを上って移動する必要があり、グローバルに警告します。

参照:

于 2009-09-27T18:55:20.960 に答える
5

これは閉鎖についてです。内部スコープでスコープ外の変数を使用できます。

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

最初の Google のリンクによる他のサンプルの詳細情報: http://blogs.msdn.com/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx

于 2009-09-27T18:44:16.543 に答える
3

概要:

スコープ チェーンは、javascript の変数名の値を解決するために使用されます。スコープ チェーンがないと、異なるスコープで複数の変数が定義されている場合、Javascript エンジンは特定の変数名に対してどの値を選択すればよいかわかりません。javascript のスコープ チェーンは字句的に定義されています。つまり、コードを見るとスコープ チェーンがどうなるかがわかります。

スコープ チェーンの一番上にあるのはグローバル スコープで、ブラウザ内のオブジェクトwindowです ( )。グローバル スコープ以外に、関数には変数の独自のスコープがあります。スコープ チェーンは、関数が定義されている場所を調べることで判断できます。globalNodeJS

変数を解決するとき、内部関数は最初に自身のスコープを調べます。変数が独自のスコープで見つからない場合、スコープ チェーンを上って、関数が定義された環境で変数名を探します。これは次のようになります。

スコープ チェーンの JavaScript

したがって、この画像の例でinnerFooは、変数を使用するときにbar、最初に innerFoo (関数本体内のコード) のスコープ内で見つけようとします。ここで見つからない場合は、スコープ チェーンをに登りfooます。fooという名前の変数もありませbarん。したがって、スコープ チェーンを上っていき、グローバル スコープを調べます。グローバル スコープには、解決される値が 10 の bar という名前の変数がありますbar

例:

let foo = 1;
let bar = 1;


function test (bar) {
   
   return function innerTestFunc () {
      let foo = 10;
      
      console.log(foo, bar);
    }
  
}

const innerTestFunc1 = test(5);
const innerTestFunc2 = test(20);


innerTestFunc1();  // logs 10, 5

innerTestFunc2();  // logs 10, 20

上記の例では、関数を返す関数があります。innerTestFunc1まず、この関数を変数andに格納しますinnerTestFunc2。これにより、基本的に外部環境のスコープチェーンのスナップショットであるクロージャーが作成されます。

次に、関数が実行されると、関数は変数fooとの両方の値を必要としbarます。foo の値は のレベルで解決できinnerTestFunc、どちらも 10 です。10 は で既に検出されてinnerFooいるため、foo のスコープ チェーンをたどる必要はありません。

変数の場合bar、関数は でそれを見つけることができませんinnerFoo。したがって、スコープ チェーンを上っていきます。bar最初に function 内の variable に遭遇するtestためbar、 value をテスト関数内の値 (この例では 5, 20) に解決します。

于 2018-09-02T08:18:46.673 に答える