函数表达式前面的 JavaScript 加号

JavaScript plus sign in front of function expression

提问人:jOpacic 提问时间:11/12/2012 最后编辑:Robert SiemerjOpacic 更新时间:10/16/2022 访问量:94090

问:

我一直在寻找有关立即调用函数的信息,在某个地方我偶然发现了这个符号:

+function(){console.log("Something.")}()

有人可以向我解释一下函数前面的标志是什么意思/做什么吗?+

JavaScript 函数 运算符 iife self-invoking-function

评论

17赞 Mathias Bynens 11/14/2012
本·阿尔曼(Ben Alman)在这里解释了这一切: mths.be/iife
1赞 Bergi 8/20/2014
相关新闻: 感叹号在函数之前有什么作用?

答:

1360赞 T.J. Crowder 11/12/2012 #1

它强制解析器将 后面的部分视为表达式。这通常用于立即调用的函数,例如:+

+function() { console.log("Foo!"); }();

如果没有 there,如果解析器处于需要语句(可以是一个表达式或几个非表达式语句)的状态,则该单词看起来像是函数声明的开头,而不是函数表达式的开头,因此后面的单词(上面行末尾的那些)将是一个语法错误(就像名称的缺失一样, 在那个例子中)。使用 ,它使其成为函数表达式,这意味着名称是可选的,并导致对函数的引用,可以调用该函数,因此括号有效。+function()+

+只是选项之一。它也可以是 、 、 或几乎任何其他一元运算符。或者,您可以使用括号(这更常见,但在语法上既不正确也不更不正确):-!~

(function() { console.log("Foo!"); })();
// or
(function() { console.log("Foo!"); }());

评论

13赞 Kundan Singh Chouhan 11/12/2012
更多详细说明在这里,benalman.com/news/2010/11/......
170赞 Chris 11/14/2012
难道我们不能说 paren-wrapping 是一种高级符号吗?我非常熟悉用于包含表达式的 parens。如果您还不知道 js 的这个神秘怪癖,那么在这种情况下 + 在做什么就完全不清楚了。
1赞 Beetroot-Beetroot 8/12/2013
注意:在两个 parens 选项中,jsLint 更喜欢第二个选项。我认为 jsHint 不那么挑剔。
45赞 Ville 10/22/2014
使用“plus”表示法的常用库之一是 Bootstrap(这就是我最终阅读此线程的方式)。
0赞 AlexGrafe 10/26/2014
顺便说一句,Bootstrap 正在这样做:maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js
102赞 Phil H 11/12/2012 #2

作为 @TJCrowder 答案的附属,通常用于强制对值进行数值转换,如此 SO 答案所解释的那样。在这种情况下,它被称为“一元加运算符”(为了便于谷歌搜索)。+

var num = +variant;

因此,在函数前面,它可以是一种强制将函数的结果解释为数字的方法。我怀疑它是否发生,但从理论上讲,JIT 可以使用它来将函数编译为纯数字函数等。但是,为了防止一元加号在较大的表达式中使用时成为串联,您需要括号:

blah + (+(function(){ var scope; return "4"; })());

评论

5赞 Catherine 11/16/2012
这怎么会获得 37 个赞成票?表示法永远无法在没有错误的情况下执行(除了这不能回答问题的事实)。(+function() { ... })()
9赞 Phil H 11/16/2012
@whitequark:错过了函数+调用周围的一对大括号。怀疑赞成票更多是因为数字投的解释。
11赞 Catherine 11/16/2012
好吧,我可能在吹毛求疵。
2赞 Benjam 11/21/2013
@Christoph我倾向于把这些括号留在那里。事实上,如果它们丢失了,我甚至会添加它们。它使正在发生的事情更加清晰,并且还可以防止通过删除空格来最小化代码时出现问题,从而导致不相同。3++function...
3赞 Benjam 11/21/2013
尽管进一步思考,这本身是不必要的。可以得到相同的结果,这将否定对包装支架的需求。+function...blah + function( ){ ... }( );
65赞 Ja͢ck 11/17/2012 #3

因此,简短的回答是,它通过以一种或另一种方式使用函数结果来防止语法错误。

您还可以使用运算符指示引擎您甚至对返回值不感兴趣:void

void function() { console.log("Foo!"); }();

当然,在整个事情周围放置大括号也可以达到这个目的。

评论

51赞 Peter Wone 3/16/2015
空隙或括号是非常可取的。它们不含 WTF。使用 + 是一种不太聪明的聪明。
2赞 dudewad 11/10/2015
一个好点。似乎使用其中一个运营商会违反当前的行业标准。也许“酷孩子”开发人员会选择它,否则我仍然看不出使用某些东西而不是 void 或 () 的意义
1赞 Stas Sorokin 1/5/2022 #4

TL的;DR(快速回答)

加号将进行操作的操作数强制转换(转换)为 Number(如果尚未转换)。

解决方案与起源

函数前面的符号,实际上称为一加号,是称为一元运算符和(一元加号)的组的一部分,用于将字符串和其他表示形式转换为数字(整数或浮点数)。+

一元运算是只有一个操作数的运算,即单个操作数 输入。这与二进制操作相反,二进制操作使用两个 操作

基本用途:

const x = "1";
const y = "-1";
const n = "7.77";

console.log(+x);
// expected output: 1

console.log(+n);
// expected output: 7.77

console.log(+y);
// expected output: -1

console.log(+'');
// expected output: 0

console.log(+true);
// expected output: 1

console.log(+false);
// expected output: 0

console.log(+'hello');
// expected output: NaN

当符号位于变量、函数或任何返回的字符串表示形式之前时,输出将转换为整数或浮点数;一元运算符 () 也转换非字符串值 、 和 。++truefalsenull

高级用途

使用上述功能的正确方法是:

+function(){return "3.141"}()
// expected output: 3.141

我喜欢用一个对象变成一个时间戳,像这样:+new Date()

+new Date()
// expected output: 1641387991035

其他一元运算符

-一元否定运算符将其操作数转换为 Number 类型 然后否定它。

~按位 NOT 运算符。

!逻辑 NOT 运算符。

deletedelete 运算符从对象中删除属性。

voidvoid 运算符丢弃表达式的返回值。

typeoftypeof 运算符确定给定对象的类型。

评论

1赞 Peter Bašista 10/12/2022
一元运算符的副作用是它强制其参数为数字。在我看来,这是非常违反直觉的,特别是考虑到二进制运算符也执行字符串连接。所以变成 but become ,而不是 which 将是与空字符串连接的结果。++'hello' + 'world''helloworld'+'hello'NaN'hello'