闭包/立即执行函数

220 阅读2分钟

闭包

  1. 内部函数保存到了外部,必生成闭包。
  2. 闭包会导致原有的作用域链不释放,造成内存泄漏(占用)


以下函数想实现 从0打印到9.

function test() {
    var arr = []
    for (var i = 0; i < 10; i++) {
        //for循环丰满空数组,填入10条数据function;arr[i]每次为新的函数体
        arr[i] = function () {
            console.log(i + '')
        }
    }
    //arr返回到外部
    return arr
 }

var myArr = test()
for(var j = 0; j < 10; j++) {
    myArr[j]()
}

打印结果为10个10,因为是1对多的场景,i=10时,停止循环。

解决唯一办法:立即执行函数

立即执行函数

定义:此类函数没有声明,再一次执行后立即释放,(是和初始化工作)除此之外没有其他区别


立即执行函数的两种书写方式:    W3C建议第一种方式

  1. ( function () {
    
    } () )

  2. ( function () {
    
    } ) ()

注:只有表达式才能被执行符号执行

eg:

var test = (function () {
    console.log('a')
} () )

-----------------------------------------------------------------------------------------------

以下函数想实现 从0打印到9 (用立即执行函数解决问题)

        function test() {
            var arr = []
            for (var i = 0; i < 10; i++) {

                (function(j) {
                    //每个函数保存到arr里面的时候,他们对应的 j 不同
                    //有多少立即执行函数就有多少个 j
                    //i 每次的值会附到j 上 
                    arr[j] = function() {
                        console.log(j + '')
                    }
                }(i))

            }
            //返回arr到外部
            return arr
        }
        
        var myArr = test()
        for (var j = 0; j < 10; j++) {
            myArr[j]()
        } 

立即执行函数每次执行后释放,但他内部的 函数 被保存到了外部,并且带着立即执行函数的AO,形成了1 对 1的场景。

-----------------------------------------------------------------------------------------------

函数累加器

        function add() {
            var num = 0

            function a() {
                console.log(++num)
            }
            return a
        }
        //执行add函数,定义a函数
        var mysum = add()
        //每次执行累计加一
        mysum()
        mysum()
        mysum()

---------------------------------------------------------------------------------------------

  • 把里面的函数保存到外部,里面函数在外面执行的话,一定可以调用里面的变量。
  • 闭包产生会造成'内存泄漏',过多的占用内存,为泄露。

eg:沙子握在手上,漏得越多,剩的越少。