function init() {
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
displayName();
}
init();
init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name。
值得注意的是,因为js作用域链的关系,栈中的执行环境是从内往外找,也就是说displayName 函数的执行环境中没有变量但是从内往外找 -> init 执行环境(函数作用域) -> window 执行环境(也称全局作用域),若在全局作用域没找到就会报错。 因为变量name 是在init 中找到的,所以init函数开辟的内存中的name 变量不会被垃圾回收机制清理(直到函数displayName 实例被销毁,否则,一直存在)(注:这也是闭包的缺点之一:闭包会导致变量不会被垃圾回收机制所清除,会大量消耗内存)
见test1.js、test2.js
主要注意点,内部函数通过return将值返回给外部函数以供使用,内部函数可以使用外部函数的变量。
闭包优点:
本文章使用limfx的vscode插件快速发布