编写 IIFE 有哪些不同的方式?他们的用例是什么?
What are the different ways of writing an IIFE? What are their use cases?
我已经开始阅读 this 这本书了。第 2 章说有不同的方法来编写 IIFE:
!function (){}()
~function (){}()
+function (){}()
-function (){}()
new function (){}
1,function (){}()
1&&function (){}()
var i=function (){}()
作者说:
Each manifestation has its own unique qualities and advantages—some
with fewer bytes, some safer for concatenation, each valid and each
executable.
我是 JS 的新手。我知道 IIFE 是什么,但这些 IIFE 表格究竟有什么作用?
为什么要这样做?
在进入列表之前,让我们先从 "Why do this at all?"
开始
答案是:将函数内的任何变量和函数声明保持私有。通常这是为了避免全局变量(避免全局变量是一个好主意TM)。例如:
+function() {
function foo() {
/* ... */
}
foo();
var answer = 42;
}();
感谢 IIFE(在此上下文中称为 范围函数 ),foo
和 answer
不是全局变量。它们对函数内的代码是私有的,除非它们以某种方式导出。
即使不在全局范围内,您也可以这样做,只是为了避免污染您所在的任何范围。
IIFE 通常还有其他用途,但您引用的样式通常用于范围界定。
例子
作者 戏剧性地 夸大了 "each has its own unique qualities and advantages".
的情况
除非您使用 return 值,否则它们完全相同:
!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
、undefined
、NaN
或 false
(函数不会得到 运行)。类似地,带有 0||...
的那个只要开始它的值是假的就可以工作。
在这一个中:
var i=function (){}()
...唯一的区别是它声明了一个变量i
,它存储return 值。当然,这可能会有很大的不同。考虑这个更明显的版本:
var MyPseudoNamespace = function() {
// ...
return { /* nifty "namespace" stuff here */ };
})();
最后:
new function (){}
这将创建一个新对象,然后调用将 this
设置为新对象的函数。如果您不在函数中使用 this
,那将毫无意义。如果你这样做了,好吧,它是否有用取决于你用this
.
做什么
注意:如果有任何您无法控制的代码紧接在您的作用域函数之前的可能性(例如,当您合并和缩小文件时),最好开始 all[=其中 107=] 用 ;
关闭,例如:
;!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(){}())
自动分号插入不会启动!结果? obj.prop
函数被 调用 ,我们的 IIFE 作为参数传递给它。这将使它更明显:
obj.prop = function() {
// Do something big and awful
}(function(){}())
看看那些 ()
现在是如何调用函数的?
同理:
obj.criticalValue = 42
然后
+function(){}()
一下子,criticalValue
就乱了。为什么?因为:
obj.criticalValue = 42+function(){}()
呸!
连续多个 ;
是无害的,所以如果您从一个开始,就不太可能 运行 惹上麻烦。
将多个文件合并为一个文件是一种优化。这个想法是,如果前一个文件的最后一行没有以换行符结尾,那么这个文件的第一行从一行的中间开始。
在该函数之前添加 ;
之类的内容使其仍然可以正常工作。
我已经开始阅读 this 这本书了。第 2 章说有不同的方法来编写 IIFE:
!function (){}()
~function (){}()
+function (){}()
-function (){}()
new function (){}
1,function (){}()
1&&function (){}()
var i=function (){}()
作者说:
Each manifestation has its own unique qualities and advantages—some with fewer bytes, some safer for concatenation, each valid and each executable.
我是 JS 的新手。我知道 IIFE 是什么,但这些 IIFE 表格究竟有什么作用?
为什么要这样做?
在进入列表之前,让我们先从 "Why do this at all?"
开始答案是:将函数内的任何变量和函数声明保持私有。通常这是为了避免全局变量(避免全局变量是一个好主意TM)。例如:
+function() {
function foo() {
/* ... */
}
foo();
var answer = 42;
}();
感谢 IIFE(在此上下文中称为 范围函数 ),foo
和 answer
不是全局变量。它们对函数内的代码是私有的,除非它们以某种方式导出。
即使不在全局范围内,您也可以这样做,只是为了避免污染您所在的任何范围。
IIFE 通常还有其他用途,但您引用的样式通常用于范围界定。
例子
作者 戏剧性地 夸大了 "each has its own unique qualities and advantages".
的情况除非您使用 return 值,否则它们完全相同:
!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
、undefined
、NaN
或 false
(函数不会得到 运行)。类似地,带有 0||...
的那个只要开始它的值是假的就可以工作。
在这一个中:
var i=function (){}()
...唯一的区别是它声明了一个变量i
,它存储return 值。当然,这可能会有很大的不同。考虑这个更明显的版本:
var MyPseudoNamespace = function() {
// ...
return { /* nifty "namespace" stuff here */ };
})();
最后:
new function (){}
这将创建一个新对象,然后调用将 this
设置为新对象的函数。如果您不在函数中使用 this
,那将毫无意义。如果你这样做了,好吧,它是否有用取决于你用this
.
注意:如果有任何您无法控制的代码紧接在您的作用域函数之前的可能性(例如,当您合并和缩小文件时),最好开始 all[=其中 107=] 用 ;
关闭,例如:
;!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(){}())
自动分号插入不会启动!结果? obj.prop
函数被 调用 ,我们的 IIFE 作为参数传递给它。这将使它更明显:
obj.prop = function() {
// Do something big and awful
}(function(){}())
看看那些 ()
现在是如何调用函数的?
同理:
obj.criticalValue = 42
然后
+function(){}()
一下子,criticalValue
就乱了。为什么?因为:
obj.criticalValue = 42+function(){}()
呸!
连续多个 ;
是无害的,所以如果您从一个开始,就不太可能 运行 惹上麻烦。
将多个文件合并为一个文件是一种优化。这个想法是,如果前一个文件的最后一行没有以换行符结尾,那么这个文件的第一行从一行的中间开始。
在该函数之前添加 ;
之类的内容使其仍然可以正常工作。