简体   繁体   English

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

[英]Javascript: function declaration type important for setInterval and onComplete?

My question is basically an extension to this one: var functionName = function() {} vs function functionName() {} . 我的问题基本上是对此的扩展: var functionName = function(){}与function functionName(){} I've read through all the answers, but I think I'm still missing the answer to this question: 我已经阅读了所有答案,但我认为我仍然缺少此问题的答案:

Why does the type of function declaration matter for jQuery's onComplete event and the native setInterval method? 为什么函数声明的类型对jQuery的onComplete事件和本机setInterval方法很重要? Moreover, why does it matter for these, but not for the normal addEventListener? 而且,为什么对这些无关紧要,但对于普通的addEventListener却无关紧要?

Example with onComplete events (assuming blinkOn() is called): 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 ); };

Example with setInterval: setInterval的示例:

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

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

The reason I'd like to know is because I want consistency in my code. 我想知道的原因是因为我想要代码的一致性。 If the only way to get that is just using function a() { ... } , that's okay. 如果唯一的方法就是使用function a() { ... } ,那就可以了。 But I think var a = function() { ... } is more clear in defining scope. 但是我认为var a = function() { ... }在定义范围方面更为清晰。 And I'm just really curious. 我真的很好奇。

If you were to define your function above where your calls to the function are, you'd have no issues. 如果要在调用函数的位置上方定义函数,则不会有问题。

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

setInterval(toggleLight, 500); setInterval(toggleLight,500);

Your problem is that you're trying to access things which don't exist yet. 您的问题是您正在尝试访问尚不存在的事物。

It's the exact same thing as trying to do this: 这与尝试执行此操作完全相同:

var c = a + b,

    a = 12,
    b = 3;

When the program hits c , a and b don't exist. 当程序点击cab不存在。

Think of this as happening in three steps, for every single function: 对于每个功能,将其视为三个步骤进行:

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

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

STEP 1. 第1步。
The engine grabs the named function add and works out what it does (defines all named-functions first). 引擎抓取命名函数add并确定其功能(首先定义所有命名函数)。

STEP 2. 第2步。
The engine locates all variables in the function and sets them to undefined : 引擎在函数中找到所有变量,并将它们设置为undefined

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

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

STEP 3. 步骤3。
The engine initializes all variables in order. 引擎按顺序初始化所有变量。

// 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

So doing something like this: 所以做这样的事情:

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

Is equal to this: 等于这个:

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

Solution: 解:

Separate your implementation from your action. 将实施与行动分开。 Make sure everything is defined before you call anything. 在调用任何内容之前,请确保已定义所有内容。

Named functions are kinda created in the nowhere, so they become globally available in the scope where they are defined, where as anonymous functions assigned to an identifier are only available once the identifier they are bound to is defined. 命名函数是在任何地方创建的,因此它们在定义它们的范围内变得全局可用,因为分配给标识符的匿名函数仅在定义了绑定到标识符的标识符后才可用。

So what you are running into there is a simple race condition problem. 因此,您遇到的是一个简单的竞争条件问题。 Your first non-working example should work in case blinkOn() is called after the blikOff variable definition. 如果在blikOff变量定义之后调用blinkOn()则第一个无效示例应该可以使用。

Your second non-working example doesn't work because onTimer is not yet defined when setInterval is invoked. 您的第二个无效示例不起作用,因为在调用setInterval onTimer Move the variable definition before the setInterval call and it will work. 将变量定义setInterval调用之前,它将起作用。

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

It will be called. 它将被调用。 You just have to make sure that blinkOn is not called (referenced is okay) before (above) the assignment. 您只需要确保在分配之前(上方)未调用 blinkOn (被引用就可以)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM