在变量声明和函数构造中命名函数是否有功能上的原因?
Yes. function bar() {}
导致函数的name
属性要设置为bar
,这对于例如堆栈跟踪中的调试很有用。
关于您提到的一些命名混乱,这可能会有所帮助:
function bar() {}
^ 这是一个函数声明,因为它不作为赋值表达式的一部分存在。
var foo = function() {};
^ 这是一个赋值表达式其中右侧操作数是函数表达式,其中函数表达式定义了匿名函数.
var foo = function bar() {};
^ 这是一个赋值表达式其中右侧操作数是函数表达式,其中函数表达式定义了命名函数.
可能值得注意的是函数声明可以通过函数名在本地引用,因此以下语句是roughly相等的:
function bar() {}
var bar = function() {};
I say roughly等价的,因为第二个语句仍然会导致匿名的函数,而不是一个named功能。函数声明的提升方式也存在细微的差别。例如,考虑以下情况:
function test() {
hello();
var hello = function () { console.log('hello'); };
}
test();
// > TypeError: hello is not a function
注意hello
从技术上讲,它是在我们尝试调用它的地方定义的(例外是它还不是一个函数)。这是由于变量提升造成的。但正如预期的那样,我们还没有assigned我们的功能是hello
多变的。实际上,这比解释更容易。基本上,由于吊装,以上test
示例相当于:
function test() {
var hello; // declared, but not assigned yet
hello();
hello = function () { console.log('hello'); }; // now the assignment happens
}
将其与实际的函数声明进行比较:
function test() {
hello();
function hello() { console.log('hello'); };
}
test();
// > "hello"
请注意,即使声明是below调用命令,它仍然有效,因为函数声明作为一个整体被提升到其作用域的顶部(在这种情况下,test
).
如果这令人困惑,这里有一个更简洁的行为描述可能会有所帮助:声明被吊起, not 作业。只要您了解函数声明和函数表达式之间的区别,您就需要知道这些。 :)