javascript函数前导bang!语法

uujelgoq  于 2023-02-07  发布在  Java
关注(0)|答案(7)|浏览(183)

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

!function(){
  // do stuff
}();

作为更常见的

(function(){
  // do stuff
})();

用于自调用匿名函数。
我想知道一些事情。首先,是什么让上面的例子能够真正工作?为什么为了使这个语句语法正确,必须使用bang?我还被告知+可以工作,而且我确信还有其他一些例子可以代替!
第二,它的好处是什么?我能告诉你的是它节省了一个字符,但我无法想象这是一个如此巨大的好处,吸引了众多的采用者。还有什么其他的好处我错过了吗?
我能看到的唯一的另一个区别是self调用函数的返回值,但是在这两个例子中,我们并不关心函数的返回值,因为它只用于创建闭包,所以有人能告诉我为什么要使用第一种语法吗?

0qx6xfy6

0qx6xfy61#

理想情况下,您应该能够简单地完成所有这些操作:

function(){
  // do stuff
}();

这意味着声明匿名函数并执行它,但由于JS语法的特殊性,这不会起作用。
因此,实现这一点的最短形式是使用一些表达式,例如UnaryExpression(以及CallExpression):

!function(){
  // do stuff
}();

或者为了好玩:

-function(){
  // do stuff
}();

或者:

+function(){
  // do stuff
}();

或者甚至:

~function(){
  // do stuff
  return 0;
}( );
4c8rllxm

4c8rllxm2#

在Javascript中,以function开头的行应该是一个函数 * 语句 *,应该如下所示

function doSomething() {
}

像这样的自调用函数

function(){
  // do stuff
}();

不符合这种形式(并且会在第一个开括号处导致语法错误,因为没有函数名),所以方括号用于描述匿名函数 expression

(function(){
  // do stuff
})();

但是任何创建表达式(相对于函数语句)的东西都可以,所以!也是如此,它告诉解释器这不是一个函数语句,除此之外,运算符优先级规定函数在求反之前被调用。
我不知道这个约定,但如果它变得普遍,它可能会有助于可读性。我的意思是,任何人在阅读一大块代码的顶部!function时都会期望自调用,就像我们在看到(function时已经习惯于期望相同的方式一样。除了我们将失去那些烦人的括号。我希望这就是原因。而不是速度或字符计数的任何节省。

7bsow1i6

7bsow1i63#

除了前面已经说过的内容,如果你编写的javascript不带分号,那么带!的语法是很有用的:

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

i = 2
(function(){
  console.log('cheese')
})()

第一个示例按预期输出'ham',但第二个示例将抛出一个错误,因为i = 2语句由于后面的括号而没有终止。
同样,在连接的javascript文件中,你不必担心前面的代码是否缺少分号。(函数(){})();以确保你自己的安全。
我知道我的回答有点晚了,但我想它还没有被提到:)

drnojrws

drnojrws4#

首先,jsPerf显示使用!(UnaryExpression's)通常更快,有时候它们是相等的,但当它们不相等时,我还没有看到 * 非banged * 的一个比其他的更胜一筹:http://jsperf.com/bang-function
这是在最新的Ubuntu上用最老的(比如说...)Chrome 8版测试的,所以结果可能会有所不同。
编辑:像delete这样疯狂的东西怎么样?

delete function() {
   alert("Hi!"); 
}();

还是void

void function() {
   alert("Hi!"); 
}();
e7arh2l6

e7arh2l65#

因此,对于negate“!”和所有其他一元运算符,如+、-、~、delete、void,我们已经讲了很多,总结如下:

!function(){
  alert("Hi!");
}();

或者

void function(){
  alert("Hi!");
}();

或者

delete function(){
  alert("Hi!");
}();

还有几个binary operators的案例是为了好玩:)
或者
或者
甚至
离开三元给别人家伙:)

tcomlyy6

tcomlyy66#

正如here所示,在javascript中实现自调用方法的最佳方法是使用:

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

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

(function(){})(); -> 69,564,370 ops/sec
xqk2d5yq

xqk2d5yq7#

使用void operator是一项很好的任务,因为它强制表达式求值。

void function () { console.log('IIFE'); }();

相关问题