为什么我要将函数声明分配给一个命名变量?

4
编辑:它不是将函数声明分配给命名变量的任务 - 请查看已接受的答案。标题仍然保持原样,因为其他人可能会犯与我相同的错误。

在阅读Paul Irish的infinitescroll jQuery插件代码时,我一次又一次地遇到了以下模式:

...
_create : function infscr_create (options, callback) { /* ... */ },
...

这样做有什么好处,而不是:
...
_create : function (options, callback) { /* ... */ },
...
2个回答

6
那个(被称为“命名函数表达式”)的好处是函数有一个实际的名称。在您的第二个版本中,属性有一个名称,但函数没有。给函数实际名称可帮助您的工具帮助您(调用堆栈列表、断点列表等)。更多信息:匿名问题 缺点是在某些有问题的JavaScript引擎中会产生意外结果,例如IE8及更早版本中的一个引擎。在IE8及更早版本中,Paul Irish的版本会在两个完全不同的时间创建两个不同的函数。但是,除非您保留并使用对它们的引用,并且期望它们是相同的函数(例如,在连接和取消事件处理程序时),否则这不是真正的问题。考虑到这是Paul,我猜他一定不会这样做。
关于您的问题标题:请注意,它不是函数声明,但您可能会认为它是,因为它看起来几乎完全像一个函数声明。 :-) 它是一个函数表达式。函数声明和函数表达式发生在完全不同的时间,并且对它们创建的范围会产生不同的影响。
只是为了完整性:
// This is a function declaration -- note that it's not a "right-hand
// value", e.g., we're not using the result of it immediately (via an
// assignment, a property initializer, calling it, or passing it into
// a function as an argument -- none of those).
//
// Declarations happen upon entry to the scope (not as part of step-by-
// step code). The function's name is added to the scope in which it's
// declared. Declarations are illegal inside branches (`if`, `try/catch`,
// `for`, etc.), but some engines will rewrite them as expressions for
// you if you do that. Others will not, they'll just always declare the
// function regardless of whether the code was reached. So don't do that.
function foo() {
}

// These are all anonymous function expressions. The function in the
// expression has no name, although some debuggers are pretty smart
// about looking at the expression and (where they can) listing a
// kind of pseudo-name for the function. Others are not that smart,
// which is why I avoid anonymous functions.
//
// Expressions happen when they're reached in step-by-step code.
var f = function() { };
var obj = {
    prop: function() { }
};
doSomethingCoolWithAFunction(function() { });
(function() { })(); // Call it immediately
!function() { }();  // Call it immediately
~function() { }();  // Call it immediately, there are a few variants

// These are all *named* function expressions.
//
// Since they're expressions, they happen when they're reached in the
// step-by-step code. The function's name is NOT added to the containing
// scope (except by engines with bugs).
//
// These are the same examples as above, but with a name. No other changes.
var f = function foo() { };
var obj = {
    prop: function foo() { }
};
doSomethingCoolWithAFunction(function foo() { });
(function foo() { })(); // Call it immediately
!function foo() { }();  // Call it immediately
~function foo() { }();  // Call it immediately, there are a few variants

@timkg:不用谢,很高兴能帮到你。有趣的是,可以比较在IE8及更早版本中与任何现代浏览器中这些测试的结果。 :-) - T.J. Crowder

5
  1. 该函数有一个名称,而不是匿名函数;这可以在调试跟踪中显示,从而更容易进行调试。
  2. 该函数可以通过调用infscr_create()来调用自身。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接