为什么要使用"+"(加号)或"!"IIFE中的(逻辑非)运算符



我知道IIFE的典型形式是:

(function(){/* code */})()

然而,最近我发现了一个新的:

!function(){/* code */}()
+function(){/* code */}()

其也作为IIFE工作。

我认为在第一个!中,值是布尔值,所以代码等价于true(),在第二个+中,值为数字,所以代码与NaN()相同?但true()NaN()不可能工作,而上述两种形式工作得很好。

这两种形式的IIFE是如何运作的?

function关键字具有决斗目的。根据您在其中使用的上下文,它可以启动函数声明,也可以启动函数表达式。

函数声明在当前函数的作用域中声明一个(已提升的(局部变量,并将该函数分配给该变量。

函数表达式不需要,它们要求您立即对函数执行操作。常见的例子包括将其分配给对象的属性,将其作为参数传递给函数(即使其成为回调函数(或将其用作IIFE。

如果您尝试使用()遵循函数声明,则它将出错。

function myFunction() {
console.log("Example");
}();

只有函数表达式才能立即调用函数表达式。(箭头函数也可以,但IIFE比它们老得多(。

因此,要使用IIFE,您必须执行操作来更改function关键字出现的上下文,以便它用于创建表达式而不是声明。

经典的方法是将函数封装在括号中。

(function myFunction() {
console.log("Example");
})();

但是任何使其成为表达式的都会起作用。

将运算符(如!+(放在function关键字前面可以做到这一点。

!将取调用IIFE的返回值并将其转换为否定布尔值,+将其转换成不是点的数字。运算符的左手边没有任何内容,因此值将被丢弃。

这只是使function关键字创建一个可以转换为IIFE的函数表达式的一种方法。


请注意,IIFE的主要优势也由块范围的变量(letconst(和JavaScript模块提供,因此在2022年根本没有太多理由使用IIFE。

!function() {}()+function() {}()的情况下,JavaScript将首先计算给定语句/IIFE的右手边,然后在!的情况下将IIFE的返回值强制转换为布尔值,在+的情况下强制转换为类型号。如果IIFE返回布尔值,则!将否定返回值。

示例

console.log(
!function() {
return "something";
}()
); 
/**
!function() {
return "something";
}()
evaluates to
!"something" and not true() or false()
lastly !"something" is equivalent to false
*/

有很多方法可以让函数在定义后立即执行。常见的是,您必须确保函数不是被解释为函数语句,而是被解释为一个函数表达式

通过在函数关键字前面加一个一元运算符,如!+,或任何其他一元运算符(~-void等(,可以避免function被解释为语句

任务也会起作用:

var x = function(){/* code */}()

或数组文字:

[function(){/* code */}()]

或者将其作为参数传递给(廉价的(函数:

Object(function(){/* code */}())

或者应用二进制运算符,前提是函数表达式是第二个操作数而不是第一个操作数。此处使用逗号运算符:

0,function(){/* code */}()

最新更新