3
var timers = {                                                  //#1

    timerID: 0,                                                   //#2
    timers: [],                                                   //#2

    add: function(fn) {                                           //#3
        this.timers.push(fn);
    },

    start: function runNext() {                                   //#4
        if (this.timerID) return;
        (function() {
            if (timers.timers.length > 0) {
                for (var i = 0; i < timers.timers.length; i++) {
                    if (timers.timers[i]() === false) {
                        timers.timers.splice(i,1);
                        i--;
                    }
                }
                timers.timerID = setTimeout(runNext, 0);
            }
        })();
    },

上記のコードは、John Resig によるSecrets of the JavaScript Ninjaからのものです。私が理解していない部分は、彼が関数をプロパティに割り当ててから、startその関数に名前を付ける場所ですrunNext。誰か説明をお願いできますか?

4

2 に答える 2

2

関数の「名前」は、 FunctionExpression 1で使用される場合に特に役立つ特別な役割も果たします。

x = function theFunc (z) {
    // theFunc is in scope here, and so can be used to refer
    // to the function itself in a recursive manner
    //   (in the posted code it is used with setTimeout)
    return z > 0 ? theFunc(z - 1) * z : 1;
};
// theFunc is NOT in scope here in valid ECMAScript; IE quirks anyone?

とは異なりxtheFunc上記は常に特定の関数オブジェクトを参照します。この名前がないと、関数に再帰的にアクセスするために追加のクロージャー (またはthis配管の使用) が必要になります。また、タイト バインディングは、現在のバインディングとは独立theFuncています。これは、this良い場合も悪い場合もあります。setTimeouttheFuncthis.timerID

ECMAScript 第 3 版では、関数名 (識別子) と arguments.callee は、スコープ内の同じ関数オブジェクトに評価されます。ただし、arguments.callee は、ECMAScript 第 5 版の「厳密」モードでは無効です。

この名前は、スタック トレースtoString()およびname/ displayName(実装されている場合) にも表示される場合があります。


1 ES5注釈付き、関数宣言から:

FunctionExpression の Identifier は、FunctionExpression の FunctionBody 内から参照して、関数が自身を再帰的に呼び出すことができます。

于 2013-05-17T03:27:13.800 に答える
-1

JavaScript では、すべてがメンバーを持つオブジェクトであり、それらのメンバーは、入力した内容に応じてプロパティまたはメソッドとして機能します。

この場合、timerには、メソッドとして使用されるメンバーがいくつかあります (addおよびstart)。そのために、functionコードへの参照が含まれます。start彼が( )内のコード参照に名前を付けた唯一の理由は、runNextその関数を内部から再帰的に呼び出すことができるようにするためです。の中にある 2 番目の関数参照はrunNext、何にも割り当てられていない別の無名関数参照ですが、その時点で に対して何かを返すようにするためのものですrunNext

于 2013-05-17T03:42:42.430 に答える