一. 立即执行函数
概念:
立即执行函数(IIFE)就是匿名函数的自调,简单来说就是这个函数是立即执行函数体的,不需要再在函数外调用这个函数体。更通俗讲就是这个函数刚出生,就执行了。
同时注意有名字的函数也可以自调
立即执行函数,执行完就立即销毁 。
重复使用变量不会让变量被污染的机制
常见的两种形式:
(function () {console.log(1)}) ()
(function () {console.log(1)} ())//W3C推荐使用
()
为执行运算符
均是将匿名函数体变成表达式,在函数或者代表函数体的变量后面加上()
变成表达式的方式还有通过 +
-
!
||
&&
在函数定义前将函数体变成表达式
例如:
1 && function(){console.log(1)}() //前者为true
0 || function(){console.log(2)}() //前者为false
二. 闭包
1.什么是闭包?
闭包比较官方的解释就是指有权访问另一个函数作用域中的变量的函数
。 简单点就是函数内部可以使用函数外部的变量
闭包也是一种特殊的对象。
2.闭包的作用:
会起到保护
和存储
的作用,避免全局变量污染。
3.优缺点
优点:
- 方便函数中声明的局部变量的调用;
- 可以在一个函数中再创建另一个函数,避免了传参的问题, 实现公有化变量,这样就逻辑紧密一些。
缺点:函数执行完,不销毁,导致作用域链的不释放,会造成内存溢出,从而让内存变少
简单例子
fn()执行之后,fn.AO在这里没有被销毁,依然存在
在这里插入代码片输出getFn()
为1
,就是getFn()调用了fn函数里的变量a,形成了闭包。
常见例子:
function fn() {
var arr = [];
for (var i = 0; i < 4; i++) {
arr[i] = function() {
console.log(i);
}
}
return arr;
}
var getFn = fn();
getFn[0]();//4
getFn[1]();//4
getFn[2]();//4
getFn[3]();//4
fn() 的输出结果均为4,但想要实现的输出结果是0、1 、2、 3
接下来改变之后的代码
function fn() {
var arr = [];
for (var i = 0; i < 4; i++) {
(function(j){
arr[j] = function (){
console.log(j);
}
}(i));
}
return arr;
}
var getFn = fn();
getFn[0]();
getFn[1]();
getFn[2]();
getFn[3]();
加了立即执行函数,让其每执行一次就销毁一次