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

时间:2015-11-11 13:07:46

标签: javascript function iife

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

!function (){}() 
~function (){}() 
+function (){}() 
-function (){}()
new function (){} 
1,function (){}() 
1&&function (){}() 
var i=function (){}()

作者说:

  

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

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

2 个答案:

答案 0 :(得分:10)

为什么这样?

在我们进入列表之前,让我们先来看看“为什么这样做?”

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

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

    foo();

    var answer = 42;
}();

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

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

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

示例

作者戏剧性地夸大了“每个人都有自己独特的品质和优势”的情况。

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

!function (){}() 
~function (){}() 
+function (){}() 
-function (){}()
1,function (){}() 
1&&function (){}() 

它们中的代码在函数中运行,作用域。

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

(function(){}())
(function(){})()
0||function (){}() 
1^function(){}() // any binary math operator in place of ^ also works

当然,上述所有内容中的1并不特别。可以是大多数数字(或其他任何数字),但使用&&的数字不适用于0""null,{{ 1}},undefinedNaN(函数无法运行)。同样,只要启动它的值为false,false的值就会起作用。

在这一个:

0||...

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

i

最后:

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

    return { /* nifty "namespace" stuff here */ };
})();

创建一个新对象,然后调用设置为新对象的new function (){} 的函数。如果你在函数中没有使用this,那就完全没有意义了。如果你这样做,那么它是否有用取决于你对this的所作所为。

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

;

其中一些技术上并不需要需要一个,但其中大部分都是。没有它们的副作用可能是微妙的,或者是灾难性的。考虑:

代码前的代码:

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

然后你的代码:

obj.prop = function() {
    // Do something big and awful
}

自动分号插入不会启动!结果? (function(){}()) 函数被称为,我们的IIFE作为参数传递给它。这将使其更加明显:

obj.prop

了解那些obj.prop = function() { // Do something big and awful }(function(){}()) 现在如何调用该函数?

类似地:

()

然后

obj.criticalValue = 42

突然,+function(){}() 搞砸了。为什么?这是因为:

criticalValue

卫生署!

连续多个obj.criticalValue = 42+function(){}() 是无害的,所以如果从一个开始,你就不太可能遇到麻烦。

答案 1 :(得分:0)

将多个文件连接成一个文件是一种优化。这样的想法是,如果前一个文件的最后一行没有以换行结束,则该文件中的第一行从一行开始。

在函数允许之前添加;之类的内容使其仍能正常工作。