2016-03-19 15 views
4

はのは例を見てみましょう:このコードブロックはどのようにJavaScriptで動作しますか?

最初:

var user = { 
    firstName: "John", 
    sayHi: function() { 
    alert(this.firstName); 
    } 
}; 

setTimeout(function() { 
    user.sayHi(); // John 
}, 1000); 

秒:

var user = { 
    firstName: "John", 
    sayHi: function() { 
    alert(this.firstName); 
    } 
}; 

setTimeout(user.sayHi, 1000);// undefined 

なぜ第二の例では未定義?そしてそれはどのように機能しますか?

答えて

4

関数参照をsetTimeout関数に渡すと、渡された関数参照はwindowのスコープ内で実行されます。だからwindow.firstNameundefinedになります。あなたはwindowのようなオブジェクトを持っていません。

var user = { 
    firstName: "John", 
    sayHi: function() { 
    alert(this.firstName); 
    } 
}; 

setTimeout(user.sayHi.bind(user), 1000); 

上記のコードでわかるように、スコープを関数参照に明示的にバインドする必要があります。また、以下のような無名関数を使用する伝統的な方法を使用することもできます。

setTimeout(function(){ user.sayHi(); }, 1000); 
+0

ありがとう、しかし私は匿名関数であなたの例をどのように動作させるのか分かりませんか?どのようにコンテキストを保存するのですか? –

+0

@JimButton無名関数ではクロージャになります。私はオブジェクトユーザーを意味します。しかし、最初のケースでは、内部的にsetTimeoutは渡された関数参照を 'reference.call(scope)'のように呼び出します。ここでscopeはオーバーライドされなかった場合はウィンドウになります。したがってthis.firstNameはwindow.firstNameに似ています。 –

+1

ご協力いただきありがとうございます! –

関連する問題