编写IIFE的不同方法有哪些?他们的用例是什么?

bat*_*man 6 javascript function iife

我已经开始阅读本书了.第2章说,编写IIFE有不同的方法:

!function (){}() 
~function (){}() 
+function (){}() 
-function (){}()
new function (){} 
1,function (){}() 
1&&function (){}() 
var i=function (){}()
Run Code Online (Sandbox Code Playgroud)

作者说:

每个表现形式都有其独特的品质和优势 - 一些具有较少的字节,一些更安全的连接,每个有效和每个可执行文件.

我是JS的新手.我知道IIFE是什么,但这些IIFE形式究竟做了什么?

T.J*_*der 10

为什么这样?

在我们进入列表之前,让我们从"为什么要这样做?"开始吧.

答案是:将函数中的任何变量和函数声明保持为私有.通常这是为了避免全局变量(避免全局变量是一个好主意TM).例如:

+function() {
    function foo() {
        /* ... */
    }

    foo();

    var answer = 42;
}();
Run Code Online (Sandbox Code Playgroud)

感谢IIFE(在此上下文中称为范围函数),fooanswer不是全局变量.除非以某种方式导出,否则它们对函数中的代码是私有的.

即使不在全球范围内,您也可以这样做,只是为了避免污染您所处的任何范围.

IIFE通常有其他用途,但您引用的样式通常用于范围界定.

例子

作者大大夸大了"每个人都有自己独特的品质和优势"的情况.

除非你使用的是返回值,否则这些都是完全相同的:

!function (){}() 
~function (){}() 
+function (){}() 
-function (){}()
1,function (){}() 
1&&function (){}() 
Run Code Online (Sandbox Code Playgroud)

其中的代码在函数中运行,作用域.

我们也可以将这些添加到该列表中:

(function(){}())
(function(){})()
0||function (){}() 
1^function(){}() // any binary math operator in place of ^ also works
Run Code Online (Sandbox Code Playgroud)

当然,上述1所有内容并不特别.可能是大多数人的任何号码(或其它任何东西),但使用一个&&不会与工作0,"",null,undefined,NaN,或false(函数不会得到运行).类似地,0||...只要启动它的值是有效的,它就是假的.

在这一个:

var i=function (){}()
Run Code Online (Sandbox Code Playgroud)

...唯一的区别是它声明了一个变量i,它存储了返回值.当然,这可能是一个很大的不同.考虑一下这个更明显的版本:

var MyPseudoNamespace = function() {
    // ...

    return { /* nifty "namespace" stuff here */ };
})();
Run Code Online (Sandbox Code Playgroud)

最后:

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

这将创建一个新对象,然后使用thisset 调用该函数到新对象.如果你不在this函数中使用它,那是完全没有意义的.如果你这样做,那么它是否有用取决于你的工作this.


注意:如果有任何代码的可能性,你不能控制在你的作用域功能之前(例如当你合并和缩小文件时),最好用a 开始所有这些;,例如:

;!function (){}() 
;~function (){}() 
;+function (){}() 
;-function (){}()
;1,function (){}() 
;1&&function (){}() 
;(function(){}())
;(function(){})()
;0||function (){}() 
;1^function(){}() // any binary math operator in place of ^ also works
Run Code Online (Sandbox Code Playgroud)

其中有几个在技术上不需要一个,但大多数都需要.没有它们的副作用可能是微妙的,或者是灾难性的.考虑:

代码前的代码:

obj.prop = function() {
    // Do something big and awful
}
Run Code Online (Sandbox Code Playgroud)

然后你的代码:

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

自动分号插入不会开始!结果?该obj.prop功能被称为,我们IIFE传递给它作为参数.这将使其更加明显:

obj.prop = function() {
    // Do something big and awful
}(function(){}())
Run Code Online (Sandbox Code Playgroud)

看看这些()是如何调用函数的?

同理:

obj.criticalValue = 42
Run Code Online (Sandbox Code Playgroud)

然后

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

突然,criticalValue搞砸了.为什么?因为:

obj.criticalValue = 42+function(){}()
Run Code Online (Sandbox Code Playgroud)

卫生署!

;连续多次是无害的,所以如果你开始使用一个,你就不太可能遇到麻烦.

  • @joews:感谢你的出色表现,我最后总结了一件事. (2认同)