IIFE(Immediately Invoked Function Expression),中文一般翻译为
匿名立即执行函数
IIFE详解
构成
IIFE包含两部分。
第一部分是一个匿名函数,它包裹在分组操作符()
中,拥有独立的词法作用域。
第二部分是再一次使用分组操作符()
,创建一个立即执行函数表达式。Javascript引擎到此将立即执行函数。
大体结构如下所示:
;(function(){
// code
})();
优点
- 匿名函数中的变量和方法,不能从外部访问
(function () {
var name = 'wall';
function sayHello(){
console.log('hello');
}
})();
// 外部不能访问变量 name 和方法 sayHello
name // undefined
sayHello() // sayHello is not defined
因为匿名函数有自己独立的词法作用域,所以会产生这种现象。
- 匿名函数中可以正常访问更高词法作用域中的变量和方法
// 浏览器环境下
var name = 'wall';
(function(){
console.log(name); // 在控制台正常输出`wall`
})();
所以,IIFE并不是双向封闭的一个模块。模块内部可以有自己的私有方法和私有变量,也可以正常使用外部环境的变量和方法。
其他表现形式
代码语言:javascript复制!function(){
}();
function(){
}();
(function(){
}());
本质上,都是先将匿名函数转变为可执行的表达式,然后再用分组操作符执行。
IIFE在lodash中的应用
先上源码:
代码语言:javascript复制;(function(){
// code
}.call(this))();
第一个;
的作用
工具库的源码,一般都是;
开始。为什么要以这个符号作为开始,其实别有深意。
- 第一个涉及到的是概念:语句
语句:是构成程序的基本单位,一条语句完成某种特定的操作。一般语句以分号
;
结束。
- 另一个涉及到的是代码的优化手段:压缩合并
在前端的
铁器时代
,YaHoo出了一个著名的压缩代码工具——YUI Compressor。它的作用之一,就是将多个js文件源码,合并到一起,变成一个新文件。以此来减少页面加载时的HTTP请求数。 多个js文件压缩,总不免会出现黑天鹅,比如以下这种:
// a.js
function say(){
// code
}
// b.js
(function(){
// code
})();
// a.js和b.js合并成c.js
// c.js
function say(){
// code
}(function(){
// code
})();
JavaScript引擎,解析c.js文件时,误将say
方法进行执行,导致不可思议的事情发生。
而加上分号之后,则可以杜绝这种情况。
call的作用
call的使用,是为了显式指定当前匿名函数的上下文(context),由引用该工具库的环境所决定。
代码语言:javascript复制function Foo(){
(function(){
console.log(this); //Foo
}).call(this);
(function(){
console.log(this); //undefined in strict or global
})();
}
var test = new Foo;
参考
- MDN术语表-IIFE
- Why write “.call(this)” at the end of an javascript anonymous function?
关注我的项目(有帮助到你的话,麻烦点个star)
GitHub地址:lodash源码解读