闭包和立即执行函数

一、闭包

1、概念

[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures) 的解释:
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包

2、作用

1. 让外部访问函数内部变量成为可能;(隐藏变量)

2. 局部变量会常驻在内存中;

3. 可以避免使用全局变量,防止全局变量污染;

3、示例

1
2
3
4
5
6
7
8
9
10
11
function fn1(){
let a=1;
function b(){
console.log(a)
a+=1;
}
return b
}
const fn2=fn1()
fn2() //1
fn2() //2
这就是一个最简单的闭包,fn2 可以获取到函数内部的变量 a

二、立即调用函数表达式(IIFE)

  1. 在定义时就直接执行的函数
    1
    2
    3
    4
    (function () {
    let x=1;
    return x
    })();
  2. 可以将立即执行函数分配给一个变量,变量将得到函数的返回值
    1
    2
    3
    4
    5
     let a=(function () {
    let x=1;
    return x
    })();
    a //1
    作用:由于立即执行函数内部变量无法访问,立即执行函数可以避免变量污染。

一个经典的面试题

1
2
3
4
5
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
})
}//输出 5个5

可以使用闭包和立即执行函数

1
2
3
4
5
6
7
8
for(var i=0;i<5;i++){
(function (i) {
setTimeout(()=>{
console.log(i)
})
})(i)
}
// 依次打出0~4

或者把 var 改为 let

var 声明的 i 相当于是在全局作用域,在 for 循环结束之后才会执行,因此打出 5 个 5

而使用 let,会在每次执行 for 循环的时候重新创建一个变量 i,每次循环是一个新的作用域,因此不会打出 5 个 5