【问题标题】:JS: What's the difference between a ! closure and () closure? [duplicate]JS: 和 有什么区别!闭包和 () 闭包? [复制]
【发布时间】:2012-12-07 14:11:28
【问题描述】:

可能重复:
What does the exclamation mark do before the function?

所以我回过头来查看我自己的一些代码以及其他一些 javascript 代码,我意识到不久前当我开始编写 javascript 库时,我使用的闭包看起来像这样:

(function( window, document, undefined ) {
    // code
})( window, document );

但后来我看到了一些引导代码,我改成了这样的语法:

! function (window, document, undefined) {
    // code
}(window, document);

现在,如果我没记错(如果我错了,请纠正我),放置“!”在我的匿名函数前面只是导致它被视为'()'然后返回(到无处?)函数返回的值是否不是未定义、null或空的布尔值。

我想知道的是,使用 '!()' 语法而不是 '()()' 之间真的有区别吗?是否有某些浏览器会抱怨?

感谢您的任何想法,谢谢!呵呵

【问题讨论】:

  • stackoverflow.com/questions/3755606/…。这样做的目的是在每个函数的代码大小中节省一个额外的字节。
  • 太棒了,所以它实际上只是节省了一个字节来提高效率,然后根据我使用的闭包数量等放大。
  • 与缩小和 gzip 压缩等相比,节省的字节数显着
  • 另外,有点迂腐,这些实际上并不是闭包——它们只是匿名函数。闭包是将函数与存储在变量中的一些数据联系在一起,当您调用函数时,这些数据可能不再在范围内。 tinyhippos.com/2010/07/05/closure-in-javascript-with-examples

标签: javascript scope closures anonymous-function


【解决方案1】:

您要问的是自调用函数,也称为 IIFE (immediately invoked function expression)。这与闭包不同。虽然它确实创建了一个闭包(实际上,javascript 中的所有函数都创建了闭包,而不仅仅是 IIFE)。

您可能会混淆这两个问题是可以理解的,因为 IIFE 通常是在解释闭包的上下文中引入的。但请注意,它们是不同的东西。闭包是私有的、共享的“类全局”变量。 IIFE 是在定义后立即被调用的函数。

现在,IIFE 是如何工作的?线索就在名字里。这是“FE”IIFE - 函数表达式。

如您所知,在 javascript 中,有两种方法可以创建函数 - 使用函数声明:

function foo () {}

并使用函数表达式:

foo = function () {}

函数表达式只是在表达式的上下文*中声明的函数。 javascript中的表达式是什么?任何评估某事的语句。

传统上,人们将表达式识别为:

  1. = 符号右侧的任何内容

     a = /* expression */
    
  2. 大括号中的任何东西

    (/* expression */)
    

所以传统上这是声明函数表达式的两种“标准”方式:

foo = function(){}

(function(){})

第二种语法可以很容易地执行表达式返回的函数对象。但是,实际上,表达式是 js 进行数学(或逻辑,无论如何都是数学)的任何地方。因此,在函数声明中添加运算符也会将其转换为表达式。以下是有效的,因为它们是一元运算符(意​​思是,它们在左侧没有任何东西是合法的):

!function(){}()

+function(){}()

-function(){}()  // I especially like this one because it
                 // looks like a command line switch

typeof function(){}()

但是,如果您使用一些一次性值或变量,您也可以使用二元运算符。以下也有效:

x=function(){}()
0==function(){}()
1*function(){}()
2/function(){}()

哎呀,你甚至可以滥用三元运算符:

0?0:function(){}() // valid and works!

这并没有什么神奇之处。它不是嵌入到 javascript 中的特定语法。就像 (function(){}()) 不是 IIFE 的特定语法一样。只是在表达式中声明时,函数将自身返回为可以立即调用的对象。

但我建议不要使用上述任何非标准形式。出于同样的原因,您问了这个问题 - 大多数 javascript 程序员不习惯看到它们,这可能会导致混淆。直到你问这个问题,我自己才意识到你可以做到这一点。尽管如此,当您需要编写诸如缩小器、代码生成器等内容时,了解它还是很有用的。


* 我在这里使用的是传统定义中的“上下文”,而不是规范中定义的“上下文”的 javascript 特定含义。

【讨论】:

    【解决方案2】:

    没什么,它们只是实现同一目标的两种不同方式。 () 的可读性稍强一些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 2018-08-08
      • 2011-03-23
      • 2013-10-27
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多