Javascript:函数声明类型对setInterval和onComplete很重要?

时间:2012-10-02 16:01:06

标签: javascript jquery function events

我的问题基本上是对此问题的延伸: 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() { ... }在定义范围时更为明确。而我真的很好奇。

3 个答案:

答案 0 :(得分:2)

如果您要在函数调用上方定义函数,那么您就没有问题。

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

setInterval(toggleLight,500);

您的问题是您正在尝试访问尚不存在的内容。

这与尝试这样做完全相同:

var c = a + b,

    a = 12,
    b = 3;

当程序点击c时,ab不存在。

对于每一个功能,可以将其视为分三个步骤:

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 () {};

<强>解决方案:

将您的实施与您的行动分开。 在你打电话之前确保一切都已定义。

答案 1 :(得分:1)

命名函数在无处创建,因此它们在定义它们的范围内变为全局可用,其中分配给标识符的匿名函数仅在定义它们所绑定的标识符时才可用。

所以你遇到的是一个简单的竞争条件问题。在blinkOn()变量定义之后调用blikOff时,您的第一个非工作示例应该有用。

您的第二个非工作示例不起作用,因为在调用onTimer时尚未定义setInterval。在setInterval调用之前移动变量定义,它将起作用。

答案 2 :(得分: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不是被称为(引用是可以的)。