位置:首页 > 软件操作教程 > 编程开发 > JavaScript > 问题详情

JavaScript 定义闭包

提问人:刘团圆发布时间:2020-11-25

■知识点

    函数被调用时,会产生一个临时上下文活动对象,它是函数作用域的顶级对象,作用域内所有私有变量、参数、私有函数等都将作为上下文活动对象的属性而存在。

    函数被调用后,在默认情况下上下文活动对象会被立即释放,避免占用系统资源。但是,当函数内的私有变量、参数、私有函数等被外界引用,则这个上下文活动对象暂时会继续存在,直到所有外界引用被注销。

    但是,函数作用域是封闭的,外#无法访问。那么在什么情况下,外界可以访问到函数内的私有成员呢?

    根据作用域链,内部函数可以访问外部函数的私有成员。如果内部函数引用了外部函数的私有成员,同时内部函数又被传给外界,或者对外界开放,那么闭包体就形成了。这个外部函数就是一个闭包体,它被调用后,它的调动对象暂时不被注销,其属性会继续存在,通过内部函数,可以持续读写外部函数的私有成员。

■实例设计

    典型的闭包体是一个嵌套结构的函数。内部函数引用外部函数的私有成员,同时内部函数又被外界引用,当外部函数被调用后,就形成了闭包,这个函数也称为闭包函数。

下面是一个典型的闭包结构。

function f(x){                       //外部函数

    returnfunction(y){               //内部函数,通过返回内部函数,实现外部引用

        return x + y;                //访问外部函数的参数

    };

}

var c = f (5);                      //调用外部函数,获取引用内部函数

console.log(c(6));                  //调用内部函数,原外部函数的参数继续存在

解析过程简单描述如下。

第1步,在JavaScript脚本预编译期,声明的函数f和变量c,先被词法预解析。

第2步,在JavaScript执行期,调用函数f,并传入值5。

第3步,在解析函数f时,将创建执行环境(函数作用域),创建活动对象,把参数和私有变量、内部函数都映射为活动对象的属性。

第4步,参数x的值为5,映射到活动对象的x属性。

第5步,内部函数,通过作用域链,引用了参数x,但是还没有被执行。

第6步,外部函数被调用后,返回内部函数,导致内部函数被外界变量c引用。

第7步,JavaScript解析器检测到外部函数活动对象的属性被外界引用,无法注销该活动对象,于是在内存中继续维持该对象的存在。

第8步,当调用c,即调用内部函数时,可以看到外部函数的参数x存储的值继续存在,于是也就可以实现后续运算操作,返回x+y=5+6=ll。

■小结

下面的结构形式也可以形成闭包:通过全局变S引用内部函数,实现内部函数对外开放。

var c;                        //声明全局变量

function f(x){                //外部函数

    c = function(y){          //内部函数,通过向全局变量开放实现外部引用

        return x + y;         //访问外部函数的参数

    };

}

f (5);                        //调用外部函数

console.log(c(6));            //使用全局变量c调用内部函数,返回11

继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部