一:变量的作用域
学习闭包之前,必须理解JavaScript的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
- 函数内部可以直接读取全局变量
const a = 'xss';
function f1() {
console.log(a);
}
f1(); // xss
- 函数外部自然无法读取函数内部的局部变量
function f1() {
var a = 'xss';
}
console.log(a); // undefined
二:如何从外部读取到局部变量?
- 在函数的内部,再定义一个函数
function f1() {
const a = 'xss';
function f2() {
const b = 'disable';
console.log(a); // xss
}
console.log(b); // b is not defined
f2();
}
f1();
// xss
// b is not defined
上述代码中,函数f2被包括在f1的内部,所以f1内部所有的局部变量,对f2都是可见的。但是反过来是不行的,f2的局部变量对f1是不可见的.
f2可以读取到f1中的局部变量,当把f2作为返回值时,我们就可以在f1外部读取f1的内部变量了。
function f1() {
var n = 'xss';
function f2() {
console.log(n); // xss
}
return f2;
}
const res = f1(); // f2
res(); // xss
三:闭包的概念:
上述代码中,f2函数就是闭包,闭包就是能够读取其他函数内部变量的函数。
由于在JavaScript语言中,只有函数内部的自函数才能读取局部变量,因此可以把闭包简单理解成‘定义在一个函数内部的函数’。
所以,本质上,闭包就是将函数内部与函数外部连接起来的一座桥梁。
四:使用闭包的注意事项
- 由于闭包会使得函数中的变量都存在与内存中,内存消耗很大,所以
请勿滥用闭包,否则会造成网页性能问题,在IE中可能导致内存泄漏。
解决方法: 退出函数前,将不使用的局部变量全部删除
- 闭包会在父函数外部改变父函数内部的值。