在了解立即执行函数(IIFE)之前,我们需要先搞清楚函数声明、函数表达式及匿名函数的区别。
//函数声明
function (){
console.log('函数声明');
}
//函数表达式
var test = function(){
console.log('函数表达式');
}
//匿名函数
functioni(){
console.log('匿名函数');
}
常见的两种立即执行函数形式:
//形式一
(function(param){
console.log(param) //123
})(123);
//形式二
(function(param){
console.log(param); //123
}(123))
这两种写法是等价的。
一个表达式后面加上括号(),该表达式会立即执行。
解析器解析function关键字的时候,默认是认为function声明,而不是function表达式。
JavaScript语法里括弧()里面不能包含语句,所以解析器在解析function关键字的时候,会将相应的代码解析成function表达式,而不是function声明。
要想立即执行函数做到立即执行,我们需要注意两点:
- 一是函数体后面要有小括号()。
- 二是函数体必须是函数表达式而不能是函数声明。
除了使用()运算符之外,!、+、-、=等运算符都能起到立即执行的作用,这些运算符作用就是将匿名函数或函数声明转化为函数表达式。
!function(param){
console.log(param); //456
}(456)
+function(param){
console.log(param); //456
}(456)
!function fun(param){
console.log(param); //123456
}(123456)
使用立即执行函数的好处
通过定义匿名函数,创建了一个新的函数作用域,相当于创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏污染全局的命名空间。
此时若想访问全局对象,将全局对象以参数形式传进去即可。
(function(window){
})(window);
作用域的隔离非常重要,一个JS框架必须支持此功能。
var counter = (function(){
//私有变量
var i = 0;
//暴露给外部的对象
return {
get: function(){
return i;
},
set: function(value){
i = value;
},
increment: function(){
return ++i;
}
};
})();
counter.get() //0
counter.set(2)
counter.get() //2
counter.increment()
counter.get() //3
counter.i //undefined
i 不是返回对象的属性,所以无法访问到,i只存在于闭包中。
参考文章:
Doggy
ben cherry
铸剑师