使用Javascript函数表达式的首选方式是什么?

使用Javascript函数表达式的首选方式是什么?,javascript,function-expression,Javascript,Function Expression,我在调用JavaScript函数表达式时看到了这些不同的模式: 模式#1 模式#2 模式#3 在我的测试中,所有这些似乎都能正常工作(至少在大多数当前浏览器中是如此)。按照我的“口味”,模式#3更好,因为它比#1更显式,并且它在实际调用函数之前返回函数,而不是#2 但是我想知道是否有一个首选的或更正确的模式…它们都很好,你可以使用其中任何一个,推荐的模式是模式2: 我个人认为模式3很容易使用,因为它很容易遵循: var global = (function () { return thi

我在调用JavaScript函数表达式时看到了这些不同的模式:

模式#1 模式#2 模式#3 在我的测试中,所有这些似乎都能正常工作(至少在大多数当前浏览器中是如此)。按照我的“口味”,模式#3更好,因为它比#1更显式,并且它在实际调用函数之前返回函数,而不是#2


但是我想知道是否有一个首选的或更正确的模式…

它们都很好,你可以使用其中任何一个,推荐的模式是模式2:

我个人认为模式3很容易使用,因为它很容易遵循:

var global = (function () {
    return this;
})();
顺便说一句,还有其他模式/速记使用
+
等字符:

! function(){
  return this;
}();

在将函数定义为对象的属性时,我更喜欢模式一,因为您的语法会变得非常冗长。模式#1易于遵循;定义一个函数,然后调用它。模式3也有相同的功能,但后面有一组额外的
()
。在我看来,这种长篇大论会降低生产率


正如你所说,它们都是正确的,但我发现重要的是记住“奥卡姆剃刀”=>当所有事情都相同时,更简单的解释(表达式)比更复杂的解释更好。

因此,最初的问题是下面的代码:

function () {

}();
引发了一个异常。这是因为JS解析器无法自动确定它是函数声明还是函数表达式。您描述的所有模式都用于明确告诉JS“嘿,伙计,这是一个表达式”。但在您特定的情况下,您不会遇到这个问题,因为如果前面有一个变量,JS完全能够理解这是一个表达式,而不是一个声明,并且不会产生任何语法错误

在这种情况下,无需进行任何“黑客攻击”,您只需:

var _global = function () {

}();
就这样。 现在的问题是:当您需要在没有任何变量的情况下立即调用函数时,使用哪种“hack”?您描述的所有模式都可以,Crockford倾向于选择此模式:

(function(){

}());
这对我来说是有意义的,至少因为你有一个完全隔离的块,相比之下:

(function(){

})();
但是,如果您将代码与其他脚本连接,或者您有以前的代码,如果它们在末尾不使用分号,您可能会遇到一些问题:

a = b + c
(function() {

}());

在此场景中,JS考虑<代码> c>代码>函数的调用:

a = b + c(function() { }());
为了避免这种情况,开发人员通常在前面添加分号,以确保安全:

;(function() {

}());
我个人更喜欢一些操作符,比如bang(!):


这样,使用括号就不会有问题了。更少的字符,给我一种“执行”的感觉。但是,与其他方法一样,这是一种黑客行为,是个人品味的问题。例如,Crockford不喜欢很多“砰砰”的东西。

我不建议使用#1,因为如果您不将返回值赋给变量(例如,如果您仅定义函数来建立闭包,并且在空上下文中调用它),它将不起作用,您必须记住何时使用哪个构造。@amnotiam:尝试运行
function(){console.log('foobar')}()(不将其结果分配给变量),您将得到一个错误。在表达式中使用函数调用时,可以使用此样式,但如果只是调用函数而忽略返回值,则需要使用其他模式之一。在两种相似的情况下,如果有两种模式都能工作,那么必须考虑需要哪种模式是徒劳的。@lanzz:起初我不明白你的意思是没有赋值运算符,或者没有其他运算符作为表达式的一部分来计算
函数
。我以为你只是在谈论返回值。谢谢-我很好奇为什么Crockford更喜欢#2而不是#3,但也许这只是偏好的问题,那么…@Dalenbertian:你真的应该接受ZERO的答案,他解释得很好。没错,我当时在iPhone上,没有读完所有答案。。。谢谢你指出这一点+这是很好的解释:)谢谢你的详细回答!我不知道;还有!,但是我不喜欢他们!它们可能会起作用,但那就更神秘了!也许是我的“Python禅宗”在起作用:应该有(一个)明显的方法来做到这一点!:-)正如我所说,他们是黑客,因此这是个人品味的问题另外,如果您总是在第一个场景中,必须设置变量,那么您不需要它们。但是,如果你在其他人中,你必须使用或
或操作符(如
)如果您想确保不会有任何奇怪的bug,那么没有其他选择;或者,如果您想创建一个可以由您或其他人独立使用的库。这是因为有些人在行尾不使用分号,依赖于ASI(自动分号插入),但在像这样的情况下,这是必要的。
(function(){

})();
a = b + c
(function() {

}());
a = b + c(function() { }());
;(function() {

}());
!function () {

}();