在某些javascript代码中,我看到引用具有相同名称的函数的变量,例如:
var Automobile = function Automobile() {
this.someProperty = 1;
}
vs var Automobile = function() {...}
甚至:
var Automobile = function AnythingBesidesAutomobile() {...}
?
调试辅助,可能吗?
答案 0 :(得分:3)
为函数实例化中创建的函数提供本地名称使得函数可以独立于任何外部(闭包)变量来引用自身。考虑:
var foo = function() {
// do something
setTimeout(foo, 1000);
};
setTimeout(foo, 1000);
foo = 23;
因为函数内部的代码依赖于外部符号" foo"为了访问自己,事情将在第一次超时后失败。但是:
var foo = function foo() {
// do something
setTimeout(foo, 1000);
};
setTimeout(foo, 1000);
foo = 23;
现在它会起作用,因为" foo"函数内部是指function
关键字后面给出的名称,而不是" foo"在封闭范围内。
你也是正确的调试辅助工具。如果您正在设置事件处理程序(请原谅jQuery):
$(document).on('click', 'button', function() {
// do all sorts of complicated stuff
});
当出现问题时,在堆栈跟踪中显示一个名称真好:
$(document).on('click', 'button', function buttonClickHandler() {
// ...
});
最后,this used to be problematic due to bugs,但我认为在较新的JavaScript运行时环境中,很多内容已经过去了。
答案 1 :(得分:2)
你的第一个例子很少(虽然可以是你想要的时间),但名字是相同的;函数声明通常(但不总是)更合适:
function Automobile() {
this.someProperty = 1;
}
您的第二个示例更有意义,因为变量名称和函数名称不同。
在任何一种情况下,你所拥有的都称为命名函数表达式。它创建一个具有真实名称的函数(关键字function
之后的那个),在它出现的逐步代码处,并且还将该函数的引用分配给给定变量。函数的实际名称不会添加到表达式出现但在函数本身中存在的范围内;当然,变量名存在于表达式出现的范围内。
那你为什么要做第一个例子呢?函数声明不是逐步代码的一部分。它们不能出现在控制流程块内(例如,不在if
或类似内),并且在运行任何分步代码之前,它们在创建它们的上下文时发生。有时您希望等到逐步执行到达该点,在这种情况下,您使用函数表达式(在您的情况下为命名函数)。
旁注:IE8和更早的really mess up命名函数表达式,在任何可能需要在IE8及更早版本上运行的情况下都应避免使用它们。此错误在IE9及更高版本中已修复,并且在其他浏览器的当前版本中不存在。 (某些其他浏览器的旧版本与命名函数表达式有[不同]问题,但多年来都没有。)