什么是闭包?

一个函数在声明时能够记住当前作用域、父函数作用域及父函数作用域上的变量和参数的引用,直至通过作用域链上全局作用域,基本上闭包是在声明函数时创建的作用域

1、简单例子

// 全局作用域
var globalVar = "abc";
function a(){
  console.log(globalVar);
}
a(); // abc

在此示例中,当声明 a 函数时,全局作用域是 a 闭包的一部分

变量 globalVar 在图中没有值的原因是该变量的值可以根据调用函数a的位置和时间而改变。但是在上面的示例中,globalVar 变量的值为 abc

2、复杂例子

var globalVar = "global";
var outerVar = "outer"

function outerFunc(outerParam) {
  function innerFunc(innerParam) {
    console.log(globalVar, outerParam, innerParam);
  }
  return innerFunc;
}

const x = outerFunc(outerVar);
outerVar = "outer-2";
globalVar = "guess"
x("inner");//guess outer inner

(1)当调用 outerFunc 函数并将返回值 innerFunc 函数分配给变量 x 时,即使为 outerVar 变量分配了新值 outer-2,outerParam 也继续保留 outer 值,因为重新分配是在调用 outerFunc 之后发生的

(2)当调用 outerFunc 函数时,它会在作用域链中查找 outerVar 的值,此时的 outerVar 的值将为 "outer"

(3)当调用了 innerFunc 的 x 变量时,innerParam 将具有一个 inner 值,因为这是在调用中传递的值,而 globalVar 变量值为 guess,因为在调用 x 变量之前,我们将一个新值分配给 globalVar

3、错误例子

const arrFuncs = [];
for(var i = 0; i < 5; i++){
  arrFuncs.push(function (){
    return i;
  });
}
console.log(i); // 5

for (let i = 0; i < arrFuncs.length; i++) {
  console.log(arrFuncs[i]()); // 5个5
}

(1)var 关键字创建一个全局变量,当 push 一个函数时,这里返回的全局变量 i,在循环后,在该数组中调用其中一个函数时,它会打印5

(2)闭包在创建变量时,会保留该变量的引用而不是其值。可以使用 IIFES 或使用 let 来代替 var 的声明

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五秒法则

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值