javascript函数领先爆炸!句法

bra*_*rad 200 javascript syntax

我现在已经在一些库上看到了这种语法,我想知道它的好处是什么.(注意我很清楚闭包和代码在做什么,我只关心语法差异)

!function(){
  // do stuff
}();
Run Code Online (Sandbox Code Playgroud)

作为更常见的替代品

(function(){
  // do stuff
})();
Run Code Online (Sandbox Code Playgroud)

用于自我调用匿名函数.

我想知道一些事情.首先,允许顶级示例实际工作的是什么?为了使这个陈述在语法上正确,为什么必要的爆炸?我也被告知+有效,我相信其他一些代替!

第二,有什么好处?我所能说的只是它节省了一个角色,但我无法想象吸引众多采用者会带来如此巨大的好处.我还缺少其他一些好处吗?

我可以看到的唯一其他差异是自调用函数的返回值,但在这两个示例中,我们并不真正关心函数的返回值,因为它仅用于创建闭包.那么有人可以告诉我为什么人们可能会使用第一种语法吗?

c-s*_*ile 96

理想情况下,您应该能够完成所有这些:

function(){
  // do stuff
}(); 
Run Code Online (Sandbox Code Playgroud)

这意味着声明匿名函数并执行它.但由于JS语法的细节,这不起作用.

实现这一目标的最短形式是使用一些表达式,例如UnaryExpression(以及CallExpression):

!function(){
  // do stuff
}(); 
Run Code Online (Sandbox Code Playgroud)

或者为了好玩:

-function(){
  // do stuff
}(); 
Run Code Online (Sandbox Code Playgroud)

要么:

+function(){
  // do stuff
}(); 
Run Code Online (Sandbox Code Playgroud)

甚至:

~function(){
  // do stuff
  return 0;
}( );
Run Code Online (Sandbox Code Playgroud)

  • 我已将以上所有选项添加到性能测试中:http://jsperf.com/bang-function (12认同)
  • 表达我会说.在运行一次的情况下,速度并不重要. (5认同)
  • 那么*唯一*好处的简洁性? (3认同)

bra*_*jam 72

在Javascript中,一行开头应该function是一个函数语句,应该看起来像

function doSomething() {
}
Run Code Online (Sandbox Code Playgroud)

像一个自我调用的功能

function(){
  // do stuff
}();
Run Code Online (Sandbox Code Playgroud)

不适合该形式(并且会在第一个打开paren时导致语法错误,因为没有函数名称),因此括号用于描述匿名函数表达式.

(function(){
  // do stuff
})();
Run Code Online (Sandbox Code Playgroud)

但是任何创建表达式的东西(与函数语句相反)都会这样做,因此!.它告诉解释器这不是一个函数声明.除此之外,运算符优先级指示在否定之前调用该函数.

我不知道这个惯例,但如果它变得普遍,它可能有助于提高可读性.我的意思是,任何阅读!function大块代码顶部的人都会期望自我调用,我们已经习惯的方式在我们看到的情况下期望相同(function.除了我们将失去那些烦人的括号.我希望这是原因,而不是速度或字符数的节省.


Smo*_*moe 44

除了已经说过的东西,语法与!如果您编写没有分号的javascript,则非常有用:

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()
Run Code Online (Sandbox Code Playgroud)

第一个示例按预期输出'ham',但第二个示例将抛出错误,因为i = 2语句由于以下括号而未终止.

同样在连接的javascript文件中,如果前面的代码缺少分号,则不必担心.所以不需要共同的;(function(){})(); 确保你自己不会破坏.

我知道我的答案有点晚了,但我认为还没有提到:)

  • 提示和记忆的+1 ...这些天没有人喜欢写没有分号的javascript. (6认同)
  • Twitter Bootstrap是所有没有分号的JS,而且它很新......(抱歉,如果上面的评论本质上是讽刺而我错过了它). (4认同)
  • 事实并非如此.请考虑以下示例:!function(){console.log("ham");}()!function(){console.log("cheese")}(); 你收到一个错误:"SyntaxError:意外的令牌!" (2认同)

Sha*_*haz 6

首先,jsPerf表明使用!(UnaryExpression)通常更快.有时他们出来是平等的,但是当他们都没有,我还没有看到非拍着一个战胜别人太多尚未:http://jsperf.com/bang-function

这是在最新的Ubuntu上测试的,其中包含最老的(据说..)Chrome版本8.因此结果可能会有所不同.

编辑:疯狂的事情怎么样delete

delete function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

还是void

void function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢虚空,因为它明确地说"我不关心回报价值",因为它让我想起其他语言的惯例 (3认同)

Arm*_*ian 5

所以,用否定“!” 以及所有其他一元运算符,如 +、-、~、delete、void,已经说了很多,总结一下:

!function(){
  alert("Hi!");
}(); 
Run Code Online (Sandbox Code Playgroud)

或者

void function(){
  alert("Hi!");
}();
Run Code Online (Sandbox Code Playgroud)

或者

delete function(){
  alert("Hi!");
}();
Run Code Online (Sandbox Code Playgroud)

还有一些有趣的二元运算符案例:)

1 > function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

或者

1 * function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

或者

1 >>> function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

甚至

1 == function() {
   alert("Hi!"); 
}();
Run Code Online (Sandbox Code Playgroud)

将三元留给其他人:)

  • `0?0:function() { alert("Hi!"); }();` (14认同)

小智 5

正如您在这里看到的,在 javascript 中执行自调用方法的最佳方法是使用:

(function(){}()); -> 76,827,475 ops/sec

!function(){}();  -> 69,699,155 ops/sec

(function(){})(); -> 69,564,370 ops/sec
Run Code Online (Sandbox Code Playgroud)

  • 我怀疑性能是使用一种语法或另一种语法的原因。以 70M 操作/秒的速度,声明闭包将比内部代码快数千倍 (2认同)