2011-08-11 13 views
3

これは私が立ち往生したコードです。関数から無名関数を返すとき、return文の関数は関数宣言または関数式ですか?

var bind = function(func, thisValue) { 

    return function() { 

    return func.apply(thisValue, arguments); 

    } 

} 

私は実行コンテキストとクロージャについて学習しています。私の推測では、最初のreturn文の関数は、文の一部である関数式です。しかし、funcとthisValueを参照してクロージャがどのように作成されるのか分かりません。

関数式の場合、bindが呼び出されると、匿名関数はそこで評価されないため、スコープを含む[[scope]]プロパティを持つ関数オブジェクトは設定されませんバインドの実行コンテキストのしたがって、無名関数はfuncとthisValueに[[scope]]プロパティでアクセスできません。

コードが実際にクロージャを形成する場合、私の推測は間違っており、最初のreturn文の関数は関数宣言でなければなりません。または、戻り値が評価されたときに私は誤解しているかもしれませんか?これについての助けがあれば、大歓迎です!

答えて

1

これはかなり複雑に思えますが、実際は非常に簡単です。この関数の機能は、渡す引数がthisValueにバインドされている関数を返します。ここで

は一例です:

var bind = function(func, thisValue) { 
    return function() { 
     return func.apply(thisValue, arguments); 
    } 
} 

var x = { 
    "key": "the value" 
}; 
var y = { 
    "key": "the y value" 
}; 

function alert_key() { 
    alert(this.key); 
} 

var bound_function = bind(alert_key, x); 
bound_function(); // alerts "the value" 
var bound_function2 = bind(alert_key, y); 
bound_function2(); // alerts "the y value" 

それはそれはfunc.apply(thisValue, arguments)

argumentsの最初の引数がすべて含まれていますJavaScriptの変数魔法であるため、thisthis.keyにはxにバインドされていることを認識することが重要です関数に渡される引数したがって、func.apply(thisValue, arguments)は実際にはすべての引数を渡すだけですが、コンテキストはthisValue(または私の例ではxy)に設定してください。追加の引数(複数可)について

例:

var bind = function(func, thisValue) { 
    return function() { 
     return func.apply(thisValue, arguments); 
    } 
} 

var x = { 
    "key": "the value" 
}; 

function alert_key(another_value) { 
    alert(this.key + " " + another_value); 
} 

var bound_function = bind(alert_key, x); 
bound_function("another value"); // alerts "the value another value" 
bound_function("value y"); // alerts "the value value y" 
+0

このフリルで行ってくれてありがとう!それは私が何とかしていたものではありません:-)。下記参照。 – aaronfalloon

+0

ああ、わかった、私は '閉鎖'を読んで、残りの質問を飛ばした。愚かな私。 – Halcyon

2

だから私はECMAScript Language Specificationにいくつかの掘削を行なったし、返されています無名関数は関数式であるという結論になりました...そして、それは本当にそうです今はかなり単純です。関数宣言を使用して関数を定義する場合、識別子はオプションではないため、関数宣言を使用して無名関数を定義することはできません。匿名関数は、関数式を使用してのみ定義できます。これは、関数式では識別子がオプションであるためです。

私もこれを言っ...

それはバインドが呼び出されたときに、無名関数は関数オブジェクトを持っていませんので、そこを評価して、とされることはありません、関数式である場合バインドの実行コンテキストのスコープを含む[[scope]]プロパティで設定します。

私は間違っていました。関数式は、bind()が戻るときに評価されます。したがって、関数オブジェクトはそのために設定され、すべてがスコープされます。

私はいくつかの意味を作ってくれることを願っています。もし私が何かを見逃してしまったら、コメントしてください!

+0

関数宣言を簡単に識別することができます。これは 'function'キーワードで始まる文です。他のすべては関数式です。 (まあ、それほど十分ではありませんが、十分に良い... [さらに読む](http://kangax.github.com/nfe/) – user123444555621

+0

素晴らしい、リンクありがとう! – aaronfalloon