立即调用的函数表达式(即 IIFE),是一个在定义时就会立即执行的 JavaScript 函数。它可以避免污染全局作用域,而且无需定义命名函数再调用。
IIFE 有时候会让初学者感到困惑,因为它有好几种写法,今天我们就来一起看看。
分号开头
有时候你会看到用分号开头的写法:
;(function () {
// 其他代码
})();
为什么要用分号开头呢?如果你的代码前面有人忘了在变量定义语句后面加分号,在跟这段代码合并的时候,就会出错。
// 报错
var greeting = 'Hi there!'(function () {
// 其他代码
})();
// 加上分号后就OK了
var greeting = 'Hi there!';(function () {
// 其他代码
})();
关于代码风格一直有个争论,就是要不要在行尾加分号。我倾向于加分号,这不仅仅是习惯和风格问题,而是为了避免某些情况下出错。
运算符开头
!function () {
// 其他代码
}();
+function () {
// 其他代码
}();
-function () {
// 其他代码
}();
~function () {
// 其他代码
}();
// 不加运算符会报错 Uncaught SyntaxError: Function statements require a function name
function () {
// 其他代码
}();
以上写法其实都差不多,本质上是把函数声明变成表达式来执行。
改变圆括号的位置
还可以改变下圆括号的位置,把第二对圆括号放在第一对圆括号里面,效果是一样的:
(function () {
// 其他代码
}());
传参
你可能见过有人把document
和 window
当做参数传给 IIFE。这样就可以在里面使用这些全局变量的简短变量名了。
我个人倾向于对这些元素对象使用全称,看起来比较直观。但这样写也没什么问题:
(function (doc, win) {
// 其他代码
}(document, window));
还有一种写法,声明了第三个形参 undefined
,实际调用的时候不传这个参数。这样可以避免 undefined
在外部被人重写(从 ES5 开始,已经没有这个问题了),jQuery 早期就是这样做的。
(function (doc, win, undefined) {
// 其他代码
}(document, window));
应该用哪个?
我觉得最“正统”的写法是用圆括号包起来:
(function () {
// 其他代码
})();
不过,上面列举的写法都是可以的,你可以选一个自己最喜欢的形式。
更多前端技术干货尽在微信公众号:1024译站
微信公众号:1024译站
网友评论