JavaScript闭包一直是JavaScript知识体系中的重难点内容,我们要想一步到位,学好JavaScript闭包就必须稳扎稳打,一步一个脚印,毕竟心急吃不了热豆腐。只有步步为营,打下坚实的基础,我们才能够学好JavaScript闭包的知识。
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。
闭包让你可以在一个内层函数中访问到其外层函数的作用域。
在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
function init() {
var name = "Mozilla"; // name 是一个被 init函数 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
displayName();
}
init();
displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。
因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。
这个词法作用域的例子描述了分析器如何在函数嵌套的情况下解析变量名。
词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。
嵌套函数可访问声明于它们外部作用域的变量。
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
内部函数 displayName() 在执行前,从外部函数返回。但运行这段代码的效果和之前 init() 函数的示例完全一样。
原因在于,JavaScript中的函数会形成了闭包。
闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。
在本例子中,myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用。
displayName 的实例维持了一个对它的词法环境(变量 name 存在于其中)的引用。
因此,当 myFunc 被调用时,变量 name 仍然可用。
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
makeAdder 是一个函数工厂
add5 和 add10 都是闭包。
它们共享相同的函数定义,但是保存了不同的词法环境。
本文我们初步了解了JavaScript闭包的相关知识,知道了闭包的定义,以及作用域的概念,想深入学习的小伙伴可以去动力节点在线的视频课程继续学习JavaScript闭包的知识。
代码小兵49806-11 15:28
代码小兵49806-11 15:51
代码小兵49806-11 16:22
代码小兵51603-29 17:28
暴风城-小飞04-06 20:49