Javascript 命名作为对象属性值的函数的目的是什么? var定时器={/#1 timerID:0,//#2 计时器:[],/#2 加:职能(fn){/#3 这个。定时器。推(fn); }, 开始:函数runNext(){/#4 如果(this.timerID)返回; (功能(){ 如果(timers.timers.length>0){ 对于(变量i=0;i

Javascript 命名作为对象属性值的函数的目的是什么? var定时器={/#1 timerID:0,//#2 计时器:[],/#2 加:职能(fn){/#3 这个。定时器。推(fn); }, 开始:函数runNext(){/#4 如果(this.timerID)返回; (功能(){ 如果(timers.timers.length>0){ 对于(变量i=0;i,javascript,syntax,Javascript,Syntax,上面的代码来自John Resig的《JavaScript忍者的秘密》。我不明白的是,他在哪里为start属性分配了一个函数,然后将该函数命名为runNext。有人能澄清一下吗?这个“名称”函数的作用也很特殊,在1: 与x不同,上面的theFunc将始终引用特定的函数对象。如果没有此名称,则会附加一个闭包(或使用this管道)将需要递归访问函数。此外,紧密绑定使theFunc独立于当前的此绑定,这可能是好的,也可能是坏的-请注意,在调用setTimeout后,将在不同的绑定上下文中调用theFu

上面的代码来自John Resig的《JavaScript忍者的秘密》。我不明白的是,他在哪里为
start
属性分配了一个函数,然后将该函数命名为
runNext
。有人能澄清一下吗?

这个“名称”函数的作用也很特殊,在1:

x
不同,上面的
theFunc
将始终引用特定的函数对象。如果没有此名称,则会附加一个闭包(或使用
this
管道)将需要递归访问函数。此外,紧密绑定使
theFunc
独立于当前的
绑定,这可能是好的,也可能是坏的-请注意,在调用
setTimeout
后,将在不同的绑定上下文中调用
theFunc
(这也使得
this.timerID的使用成为可疑)

在ECMAScript第3版中,则函数名(标识符)和arguments.callee将对作用域内的同一函数对象求值。但是,arguments.callee在ECMAScript第5版“严格”模式下无效

名称也可能显示在堆栈跟踪中,
toString()
name
/
displayName
(如实现的那样)


1来自:

FunctionExpression中的标识符可以从FunctionExpression的FunctionBody内部引用,以允许函数递归调用自身


在JavaScript中,所有内容都是一个包含成员的对象,这些成员可以根据您在其中添加的内容充当属性或方法


在这种情况下,
timer
将有一些成员用作方法(
add
start
)。为此,它们将包含对
函数
代码的引用。他在
start
中为代码引用命名的唯一原因是(
runNext
),这样他就可以从内部递归调用该函数了。您在
runNext
中看到的第二个函数引用是另一个匿名函数引用,它甚至没有被分配给任何对象,但它只是让它在那一刻为
runNext

返回一些东西。据我所知,它通常用于调试初始化,特别是为了避免错误期间堆栈跟踪中的匿名函数。为了让函数调用自身,它需要一个名称。
setTimeout(runNext,0)
call指的是函数,如果函数完全匿名,它就不能这样做。在
setTimeout
中也会再次调用它,可能解析本地函数名比解析
计时器要快。start
也要启动吗?@Eric Jablow:这个怎么样?start
?@Mike Christensen:听起来不正确“因此可以用递归的方式引用函数本身”——他可以将其称为
this.start()
@zerkms很好的调用。我添加了一点。他可以用
这个递归运行它。下一个
。那么为什么要遵循这样一个棘手的声明呢?因为Javascript程序员喜欢黑客。是的,他可以把它放在另一个方法中,并通过
这个
调用它。他还可以把那个匿名函数从里面取出来。”是的,他可以用另一种方法"---你不需要另一个方法,你可以从自身调用它:@zerkms为什么你不能保持一致,在所有代码中使用相同的约定?如果你需要递归地调用对象中的函数,无论对象多么简单或复杂,都要始终如一地使用相同的代码。你为什么要调用它呢?我不知道它有多复杂bad@zerkms是的,但我想我指的更多的是像
“asdf”。indexOf(“s”)
,但这与你所说的不同,也与你所说的不相关。我同意这句话的措辞不恰当/正确,特别是针对重点。
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);
            }
        })();
    },
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?