0

私の質問は基本的にこれの拡張です: var functionName = function(){} vs function functionName(){}。私はすべての答えを読みましたが、私はまだこの質問への答えを逃していると思います:

jQueryのonCompleteイベントとネイティブのsetIntervalメソッドで関数宣言のタイプが重要なのはなぜですか?さらに、なぜこれらにとって重要なのに、通常のaddEventListenerにとっては重要ではないのでしょうか。

onCompleteイベントの例(blinkOn()が呼び出されると仮定):

//like this the onComplete event works normally and the functions call eachother
function blinkOn() { $blink.fadeIn( 500, blinkOff ); }
function blinkOff() { $blink.fadeOut( 500, blinkOn ); }

//like this blinkOff won't be called after the fadeIn
function blinkOn() { $blink.fadeIn( 500, blinkOff ); }
var blinkOff = function() { $blink.fadeOut( 500, blinkOn ); };

setIntervalの例:

//works fine
var timer = setInterval( onTimer, 700);
function onTimer() { ... }

//won't work
var timer = setInterval( onTimer, 700);
var onTimer = function() { ... }

私が知りたい理由は、コードに一貫性が必要だからです。それを取得する唯一の方法がを使用することである場合、それは問題ありませんfunction a() { ... }var a = function() { ... }しかし、スコープを定義する方がより明確だと思います。そして、私は本当に興味があります。

4

3 に答える 3

2

関数の呼び出しがある場所の上で関数を定義する場合、問題はありません。

var toggleLight = function(){light =!light; };

setInterval(toggleLight、500);

あなたの問題は、まだ存在していないものにアクセスしようとしていることです。

これを実行しようとするのとまったく同じです。

var c = a + b,

    a = 12,
    b = 3;

プログラムがヒットしc、存在abない場合。

これは、すべての機能について、3つのステップで発生すると考えてください。

var a = 12,
    b = 3,
    c = add(a, b);

function add (a, b) { return a + b; }

ステップ1.
エンジンは名前付き関数addを取得し、その機能を実行します(最初にすべての名前付き関数を定義します)。

ステップ2.
エンジンは関数内のすべての変数を見つけて、それらを次のように設定しますundefined

var a = undefined,
    b = undefined,
    c = undefined;

function add(a, b) { return a + b; }

ステップ3.
エンジンはすべての変数を順番に初期化します。

// 3.1
var a = 12,
    b = undefined,
    c = undefined;


// 3.2
var a = 12,
    b = 3,
    c = undefined;

// 3.3
var a = 12,
    b = 3,
    c = add(a, b); // = return a + b = 15

したがって、次のようなことを行います。

callFunction(myFunc);
var myFunc = function () {};

これに等しい:

var myFunc = undefined;
callFunction(myFunc);
myFunc = function () {};

解決:

実装をアクションから分離します。何かを呼び出す前に、すべてが定義されていることを確認してください。

于 2012-10-02T16:41:37.217 に答える
1

名前付き関数はどこからともなく作成されるため、それらが定義されているスコープでグローバルに使用できるようになります。一方、識別子に割り当てられた無名関数は、それらがバインドされている識別子が定義された後にのみ使用可能になります。

そこであなたが遭遇しているのは、単純な競合状態の問題です。最初の非動作例は、変数定義blinkOn()の後に呼び出された場合に動作するはずです。blikOff

が呼び出さonTimerれたときにまだ定義されていないため、2番目の動作しない例は機能しません。呼び出しsetIntervalの前に変数定義を移動すると、機能します。setInterval

于 2012-10-02T16:16:31.987 に答える
0
//like this blinkOff won't be called after the fadeIn
function blinkOn() { $blink.fadeIn( 500, blinkOff ); }
var blinkOff = function() { $blink.fadeOut( 500, blinkOn ); };

と呼ばれます。割り当ての前 (上) に が呼び出されblinkOnていないこと (参照されていることは問題ありません) を確認する必要があります。

于 2012-10-02T16:28:24.900 に答える