javascript基础(九)闭包

闭包应用的两种情况——函数作为返回值,函数作为参数

一、函数作为返回值

    function fn() {
        var max = 10
        return function bar(x) {
            if(x > max){
                console.log(x);   //15
            }
        }
    }

    var f1 = fn()
    f1(15)

在上面的代码中bar作为返回值,赋值给f1,通过f1(15)调用bar,将15传入,同时bar取fn作用域下的max与之比较。

二、函数作为参数被传递

    var max = 10,
        fn = function (x) {
            if(x > max){
                console.log(x);
            }
        };

        (function (f) {
            var max = 100;
            f(15);
        })(fn);

如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(15)时,max变量的取值是10,而不是100。

下面结合执行上下文环境解析一下

第一步,代码执行前执行上下文环境,并对变量赋初值,此时执行上下文环境为激活状态

第二步,执行到17行时调用fn,生成fn执行上下文环境,压栈激活

第三步,执行完fn后,按道理说应该吧fn环境出栈销毁,但是因为fn返回了一个函数bar,函数的特殊之处在于他可以创建一个作用域,而且在bar中有一个自由变量max需要引用fn中的max,因此这个max不能被销毁。

也就是说fn并没有被销毁,依然存在于执行上下文栈中。

也就是说执行到18行时,全局上下文环境被激活,但fn上下文环境依然存在于执行上下文栈中,只是没有处于激活状态,此外,18行的语句将全局上下文环境中的max赋值为100.

第四步,执行到第20行,调用f1,也就是bar,创建bar执行上下文环境,并将其激活


执行bar(15)时,需要用到自由变量max,max需要到创建bar的作用域——fn中找,fn没被销毁,所以可以找到max,这就是闭包的精髓,fn虽然执行完了,但是他的环境还在,没有被销毁。显然闭包会增加开销。

猜你喜欢

转载自blog.csdn.net/C_Ronaldo_/article/details/81041666