9

JavaScript 変数のスコープの特定のケースについて理解できないようです。私が見つけた他の例や質問とは異なり、ネストされた関数のスコープに興味があります。

この JSFiddleで例を設定しました。関連する部分は次のとおりです。

function MyObject() {
    var self = this;

    var a = 1;
    this.b = 2;

    var innerMethod = function() {
        //1 and 2: direct reference
        logMessage("a = " + a); // a = 1
        //logMessage("b = " + b); // Error: b is not defined

        //3 and 4: using this
        logMessage("this.a = " + this.a); // this.a = undefined
        logMessage("this.b = " + this.b); // this.b = undefined

        //5 and 6: using self
        logMessage("self.a = " + self.a); // self.a = undefined
        logMessage("self.b = " + self.b); // self.b = 2
    }
}

aこれで、直接参照が機能することがわかりました。this.aまた、メッセージ 3 と 4 (と) は、内部関数を参照しているthis.bため失敗することも理解しています。thisまた、元のオブジェクトへの参照を保存するため、6 行目が機能することも理解しています。

私が理解していないのは次のとおりです。

  • メッセージ 1 と 2 が同じように機能しないのはなぜですか?
  • メッセージ 5 と 6 が同じように機能しないのはなぜですか?
4

3 に答える 3

4

a変数はまさにそれ、変数です。これは、スコープinnerMethod(単なるネストされた関数) で表示されますa。これは、宣言された方法です (つまり、JavaScript にはレキシカル スコープ規則があり、内部関数は内部で定義されている関数の変数を見ることができます)。

thisMyObjectコンストラクターのローカル スコープと同じではありません。

これはofselfのエイリアスであり、独自のスコープで上書きされていることがわかりました。それでも、関数スコープのエイリアスではないため、ここでは機能しません。thisMyObjectinnerMethodthisthisself.athis.a

レキシカルスコープのより厳密な説明については、たとえばウィキペディアから始めることができます: http://en.wikipedia.org/wiki/Scope_(computer_science)

ECMA 標準http://es5.github.com/#x10.3で実行コンテキストと識別子解決規則について読むことができます。

于 2013-02-23T23:31:50.640 に答える
1

これはスコープの問題です。関数が作成されると、その周囲 (変数を含む) が保存されます。

したがって、innerMethodが作成されると、変数selfとが表示されますa

重要な概念は、関数が呼び出されたときではなく、関数が宣言されたときにスコープが作成されるということです。

あなたのケース1では、b宣言されていません(このオブジェクトは同じではありません)。

ケース 5 と 6 では、 を作成していませんself.a

于 2013-02-23T23:29:43.183 に答える
0

主な理由は、それがinnerMethodの範囲内にselfないことです。関数の所有者を参照するキーワードです。innerMethodの場合、これはインスタンス メソッドではなく、ウィンドウに属します。thisthis

function MyObject() {
    var self = this;

    var innerMethod = function() {
        alert("inner method, self == this?: " + self == this); // false
        alert("inner method: " + this); // [object Window]
        alert("closest constructor name of in prototype chain ?: "+ this.__proto__.constructor.name); // Window
    }

    this.outerMethod = function(){
        innerMethod(); 
        alert("outer method: " + this); // [object MyObject]
        alert("closest constructor name in prototype chain?: "+ this.__proto__.constructor.name); // MyObject
    }
}

var o = new MyObject();
o.outerMethod();

ここで遊べます

于 2015-02-05T11:51:35.343 に答える