黑马的介绍:
闭包 = 内层函数 + 外层函数的变量 二者缺一不可
//典型闭包 function outer(){ const a = 1 function fn(){ console.log(a) } return fn } outer() //此时外部访问不了a,但是如果函数内部是return fn 外部可以通过outer()打印a,这就保护了a的值不会被篡改javascript.info网站的介绍:
闭包是指一个函数可以记住其外部变量并可以访问这些变量。在某些编程语言中,这是不可能的,或者应该以一种特殊的方式编写函数来实现。但 如上 所述,在 JavaScript 中,所有函数都是天生闭包的(只有一个例外,将在 "new Function" 语法 中讲到)。
也就是说:JavaScript 中的函数会自动通过隐藏的[[Environment]]属性记住创建它们的位置,所以它们都可以访问外部变量。
function makeCounter() { let count = 0; return function() { return count++; }; } let counter = makeCounter(); alert( counter() ); // 0 alert( counter() ); // 1 alert( counter() ); // 2GPT的解释:
普通情况
先看这个例子:
function test() { let num = 100; console.log(num); } test();执行过程:
调用 test ↓ 创建变量 num ↓ 输出 100 ↓ test 执行结束 ↓ num 被销毁这里没有问题。
返回函数的情况
再看:
function test() { let num = 100; return function() { console.log(num); } } const fn = test();执行到这里时:
test() ↓ 创建 num ↓ 创建匿名函数 ↓ 返回匿名函数关键来了:这个匿名函数里面用到了num
function() { console.log(num); }JavaScript 引擎发现:
这个函数以后还要用到 num
所以不会立即销毁num。
而是把:
num = 100和这个函数一起保留下来。类似于:
fn ├── 函数代码 └── 关联的变量环境 num = 100这就是闭包。
我个人的理解
我之前的理解是这样的:
function makeCounter() { let count = 0; return function() { return count++; }; } let counter = makeCounter(); alert( counter() ); // 0 alert( counter() ); // 1 alert( counter() ); // 2counter这个变量拿到了返回的function(){}这个匿名函数的地址,这个函数本质上还是makeCounter里的函数。而这个地址里针对count所做的操作都是针对同一个count来进行的。
目前看来我的理解并不是很对,还是参考上面的吧。