【问题标题】:What is the preferred way to use a Javascript function expression? [closed]使用 Javascript 函数表达式的首选方法是什么? [关闭]
【发布时间】:2012-06-03 15:26:31
【问题描述】:

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

模式#1

var global = function () {
    return this;
}();

模式#2

var global = (function () {
   return this;
}());

模式#3

var global = (function () {
    return this;
})();

在我的测试中似乎一切正常(至少在大多数当前浏览器中)。在我看来,模式 #3 更好,因为它比 #1 更明确,并且它在实际调用之前返回函数,而不是 #2。

但是如果有一个更喜欢或更正确的,我正在徘徊......

【问题讨论】:

  • 我不推荐#1,因为如果您不将返回值分配给变量(例如,如果您只是定义函数来建立闭包,并且正在调用它在一个无效的上下文中),你必须记住什么时候使用哪个构造。
  • @amnotiam:尝试运行function() { console.log('foobar') }();(不将其结果分配给var),你会得到一个错误。当您在表达式中使用函数调用时,您可以使用这种样式,但是当您只是调用函数而忽略返回值时,您将需要使用其他模式之一。当两种模式都适用时,必须考虑在两种类似情况下需要哪种模式是徒劳的。
  • @lanzz:起初我不明白你的意思是没有赋值运算符或其他一些运算符来评估 function 作为表达式的一部分。我以为你只是在谈论返回值。

标签: javascript function-expression


【解决方案1】:

所以,最初的问题是下面的代码:

function () {

}();

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

在那种特定情况下,不需要任何“破解”,您可以简单地拥有:

var _global = function () {

}();

就是这样。 现在的问题是:当您需要在没有任何变量的情况下立即调用函数时,使用哪种“hack”?您描述的所有模式都可以,Crockford 更喜欢这个:

(function(){

}());

这对我来说是有道理的,至少因为你有一个完全隔离的块,相比之下:

(function(){

})();

但是,如果您将代码与其他脚本结合在一起,或者您有以前的代码,如果它们最后不使用分号,您可能会遇到一些问题:

a = b + c
(function() {

}());

在这种情况下,JS 考虑 c 一个函数的调用:

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

为避免这种情况,开发人员通常会在前面添加一个分号,以确保安全:

;(function() {

}());

我个人更喜欢一些运算符,比如 bang (!):

!function () {

}();

这样您就不会遇到使用括号的问题。更少的字符,给我一种“执行”的感觉。但是,就像其他方法一样,这是一种技巧,而且是个人品味的问题。例如,Crockford 不喜欢 A LOT 那种轰轰烈烈的东西。

【讨论】:

  • +1 这个解释很好:)
  • 感谢您的详细解答!我不知道;和!,但我不喜欢他们!他们可能会工作,但它更加神秘!也许这是我的“Python 之禅”开始了:应该有(一种)明显的方法来做到这一点! :-)
  • 正如我所说,他们是黑客,因此这是个人品味的问题。 :) 另外,如果您总是处于第一个场景中,您必须设置一个变量,那么您就不需要它们。但是,如果您在其他人中,则必须使用 or ; 或运算符(例如 !),如果您想确保不会有任何奇怪的错误,则别无选择;或者如果您想创建一个可以由您或其他人独立使用的库。那是因为有些人在行尾不使用分号,依赖于ASI(自动分号插入),但在某些情况下像这样,是必要的。
【解决方案2】:

我更喜欢模式一,因为在将函数定义为对象的属性时,你的语法会变得非常冗长。模式#1 很容易遵循;你定义一个函数然后调用它。模式 3 的作用相同,但要遵循额外的 () 集。在我看来,这种冗长会降低生产力。

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

【讨论】:

    【解决方案3】:

    它们都工作正常,你可以使用其中任何一种,Crockford 推荐的模式虽然是模式 #2:

    var global = (function () {
       return this;
    }());
    

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

    var global = (function () {
        return this;
    })();
    

    顺便说一句,还有其他使用 !+ 等字符的模式/速记:

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

    【讨论】:

    • 谢谢 - 我很好奇为什么 Crockford 更喜欢 #2 而不是 #3,但也许这只是一个偏好问题,然后......
    • @dalembertian:你真的应该接受零的回答,他解释得很好。
    • 是的,我在 iPhone 上并没有读完所有答案...感谢您指出这一点!
    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 2022-01-06
    • 1970-01-01
    • 2019-07-09
    相关资源
    最近更新 更多