了解闭包的前提,需要先知道JavaScript的变量作用域
-
全局变量
-
局部变量
const a = 1 function func(){ console.log(a); } func() // 1 函数内部可以读取全局变量
function f1(){ const a=1; } console.log(a) // Uncaught ReferenceError: a is not defined 函数外部无法读取函数内的局部变量
此外ES6的const和let本身就有块级作用域的概念。
有时候,我们就需要得到函数内的局部变量,那怎么办?闭包的出现,就是为了解决这个问题。
function f1(){
const n=1;
function f2(){
console.log(n);
}
return f2;
}
const result=f1();
result(); // 1
所以闭包的概念,我个人是这样理解:闭包是一个函数,这个函数定义在某个函数的内部。
理解有不对的地方请指正~
f2 函数就是一个闭包,这个函数定义在f1的内部。
闭包除了让外部函数可以读取函数内部的变量外,另一个用户就是让这些变量的值始终保持在内存中。
function f1() {
let n = 1;
function f2() {
n = n + 1;
console.log(n);
}
return f2;
}
const result = f1();
result(); // 2
result(); // 3
result(); // 4
result = null // 释放对闭包的引用
函数f1中的变量n一直保存在内存中,并没有在f1调用后被自动清除。因为f1是f2的父函数,而f2被赋给了全局变量result,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
闭包常见的应用场景是创建私有变量和方法
function Person() {
// 私有变量
const age = 11;
function run() {
console.log(2);
}
// 访问方法
this.getAge = function () {
return age;
};
}
const age = new Person();
console.log(age.getAge()); // 11