3

私は C++ ( Qt ) 開発者で、JS について少し知っています。以下のコードの一部が理解できません。これで私を助けてもらえますか?

function augment(withFn) {
    var name, fn;
    for (name in window) {
        fn = window[name];

        if (typeof fn === 'function') {
    // **Not able to understand below code.**
            window[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    fn.apply(this, arguments);

                }
            })(name, fn);
    // **In above code I understood everything else except this last line. 
    // Why whole function is in circular bracket? Why it ends with (name, fn);
    // What is the meaning of this?
        }
    }
}

augment(function(name, fn) {
    console.log("calling " + name);
});
4

5 に答える 5

1

括弧内の式 (「丸括弧」と呼ばれるもの) は無名関数です。(name, fn)末尾の . は、これらの引数で関数を呼び出す必要があり、戻り値が に割り当てられることを意味しますwindow[name]。これは、次のものとほぼ同等です。

tempfn = function(name, fn) { /* body */ };
window[name] = tempfn(name, fn);
于 2012-10-06T09:19:38.123 に答える
1

通常、Cでは定義(およびおそらく宣言)があります

int anon(string name, void* function) {
}

そして関数の呼び出し

anon(name, function);

丸かっこ内の部分は無名関数の宣言です。これは、パラメーターを使用してすぐに呼び出され(name, fn)ます。

と考えてください (注: JS は少し錆びている可能性があるため、構文エラーが発生する可能性があります)

 var fn2 = (function(name, fn) {
    var args = arguments;
    return function() {
      withFn.apply(this, args);
      fn.apply(this, arguments);
   });

そして、ループで

 window[name] = fn2.apply(name, fn);         
于 2012-10-06T09:20:01.493 に答える
1

ここで回避しようとしている問題は、参照namefnその後のループです。割り当てられた関数をすべて実行した場合、その特定の関数がループで定義されたときの値ではなく、最後に設定されwindow[name] = function () { alert(name); }た値が常に使用されます。nameこれを回避するには、正しい値ですぐに呼び出される関数を作成し、新しいクロージャーでそれらを保護します。詳細については、この SO-question で読むことができます:ループ内の JavaScript クロージャー – 簡単な実用例

于 2012-10-06T09:20:58.200 に答える
1

自己実行の無名関数は、ループ内のクロージャーに関する問題を解決する一般的な方法です。

したがって、実質的には、渡されたパラメーターを使用して宣言され、すぐに実行される無名関数です。

実際nameにはパラメーターは使用されていないため、そこでは役に立ちませんが、トリックを行わなかった場合、最後のfnパラメーターのみが参照として渡されます。

問題のデモンストレーション: http://jsfiddle.net/zerkms/nfjtn/

解決策 (自己実行匿名関数を使用): http://jsfiddle.net/zerkms/nfjtn/1/

于 2012-10-06T09:18:50.557 に答える
1

さて、まず第一に:

(function f(param) { alert(param); })("Hello world"); 関数を定義し、すぐに実行します。

function f(param) { alert("This: = " + this + ". Param=" + param); }
f.apply(window, "Hello world");

params を使用して、関数 fを次のコンテキストで window呼び出します(つまり、windowオブジェクトに属していると「考える」関数です)。params

function(param)無名関数への参照を返します。あれは:

var f = function(param) {...}; f("Hello world");と類似しています:

(function(param){...})("Hello world");
于 2012-10-06T09:18:53.740 に答える