在一些javascript代码中,我看到变量引用同名函数,例如:
var Automobile = function Automobile() {
this.someProperty = 1;
}那对var Automobile = function() {...}的目的是什么?
甚至:
var Automobile = function AnythingBesidesAutomobile() {...}?
调试辅助工具,可能吗?
发布于 2014-03-20 17:25:37
为函数实例化中创建的函数提供本地名称,使函数能够独立于任何外部(闭包)变量引用自身。考虑:
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() {
// ...
});最后是由于错误,这曾经是有问题的。,但我认为在较新的JavaScript运行时环境中已经解决了很多问题。
发布于 2014-03-20 17:26:59
对于您的第一个示例(虽然有时您希望这样做),名称是相同的,这一点几乎没有意义;函数声明通常(但并不总是)更合适:
function Automobile() {
this.someProperty = 1;
}第二个示例更有意义,因为变量名称和函数名不同。
在这两种情况下,您所拥有的都称为命名函数表达式。它在函数出现的逐步代码中创建一个真名函数(在关键字function之后的函数),并向给定变量指定对该函数的引用。函数的实际名称没有添加到表达式出现的范围中,而是存在于函数本身中;变量名称当然存在于表达式出现的作用域中。
那么你为什么要做第一个例子呢?函数声明不是逐步代码的一部分.它们不能出现在控制流块中(例如,不出现在if或类似块中),而且它们发生在创建它们存在的上下文时,然后才运行任何一步一步的代码。有时,您想要等到逐步执行到达那个点,在这种情况下,您使用一个函数表达式(在您的例子中是一个命名的表达式)。
附带注意: IE8和早期的真的搞砸了命名函数表达式,在可能需要在IE8和更早运行的任何情况下,您都应该避免使用它们。这个错误在IE9和更高版本中是固定的,并且在其他浏览器的当前版本中不存在。(其他一些浏览器的旧版本在命名函数表达式方面有不同的问题,但多年来没有。)
https://stackoverflow.com/questions/22540528
复制相似问题