1

私はこのブログでJSを理解するAngus Crollを読んでいて、これを見つけました

var a = {
  b: function() {
    var c = function() {
      return this;
    };
    return c();
  }
}; 

a.b();//window

私には、c を呼び出した時点で、c が b の中にあったように見えます。それが呼び出しコンテキストである必要があります(間違っている場合は修正してください)。実行すると、なぜ c() の context(this) が wi​​ndow なのですか?

そのブログで見つけた別の例があります

var a = {
  b: function() {
    return (function() {return this;})();
  }
};

a.b(); //window

なぜ b のコンテキストはウィンドウですか? 匿名関数は常にグローバル コンテキストで実行されますか?

4

2 に答える 2

2

理解するための良い方法は次のthisとおりです(しゃれが意図されています):

関数内の の値はthis、関数の呼び出し方法によって決まります。1 つの例外を除いて、関数が定義されている場所、内部にネストされている他の関数、関数が一部として定義されているオブジェクト、関数の種類などとは関係ありません。

foo.bar()またはfoo[bar]()のようなメソッド呼び出しを使用して関数を呼び出すと、関数this内にfooオブジェクトがあります。

のような通常の関数呼び出しで関数を呼び出す場合foo()this関数内はwindowオブジェクトであり、関数が厳密モードを使用する場合は ですundefined

これは 1 つの例外です。関数自体またはその周囲のコードが単純な関数呼び出しに対して"use strict";変更されている場合です。this違いを生むべきではない良いコードについては、とにかくオブジェクトであることに依存するコードを書くべきではありませthiswindow

それ以外の場合、気thisにするのは、メソッド呼び出しでオブジェクトが参照するものです。そしてそれは、関数の定義方法ではなく、関数の呼び出し方法によって常に決定されます。

最初の例を見てみましょう。

を呼び出すときは、オブジェクトのメソッドとしてa.b()呼び出しています。したがって、関数内では、 と同じです。babthisa

たまたま、それを知っても何のb役にも立ちません。関数は に対して何もしないからthisです。c()通常の関数として呼び出すだけです。cそのため、内部thiswindowオブジェクトです。またはundefined、厳密モードの場合はそうなります。

このc関数は単にそのthis値またはを返しますwindow。そして、それは からの戻り値でもありますb。これが、結果として表示される理由です。すべては、コードが関数と関数をwindow呼び出す方法に由来します。bc

次に、2 番目の例について説明します。これはひどく難読化されたコードですよね。誰がこのコードを書き、誰でも一目で理解できると期待するでしょうか?

それでは、より読みやすい形式に変換しましょう。この行が問題です:

    return (function() {return this;})();

括弧で囲まれた関数式を取り出してみましょう:

    (function() {return this;})

それを一時変数に割り当てます。

    var temp = (function() {return this;});

余分な括弧はもう必要ありません。読みやすくするためにコードをインデントしましょう。

    var temp = function() {
        return this;
    };

そして、その変数をステートメントtempで関数として呼び出すことができます。return

    return temp();

bこれをコード例の関数に戻すことができます。

var a = {
  b: function() {
    var temp = function() {
        return this;
    };
    return temp();
  }
};

a.b(); //window

おい!そのコードは見覚えがありませんか? temp実際、変数の名前を除いて、最初の例と同じです。これで、最初のものと同じように機能する理由がわかります。

于 2013-12-01T06:16:04.993 に答える