JS闭包学习

1、作用域

        作用域就是可以访问的变量的范围。

        ES5:全局用域、局部作用域(函数作用域);ES6:新增块级作用域。

        注:在JS中所有没有被赋值的变量均为全局变量;在局部作用域定义的变量,只能在函数内部访问,当函数执行完之后,这个局部变量也相应的被销毁。

2、闭包概念

        可以访问其他函数内部变量的函数,通常情况下,函数内部的变量是无法在函数外部无法访问的,因此使用闭包的作用就具备实现了能在外部访问某个函数内部变量的功能。

3、闭包产生的原因

        作用域链:当访问一个变量时,代码解释器会首先在当前的作用域中查找,如果没有找到就去父级作用域去查找,直到找到该变量或者不存在父级作用域中。

        闭包产生的本质就是:当前环境中存在指向父级作用域的引用。

        问题1:是不是只有返回函数才算产生了闭包?

        解:其实也不是,只需要让父级作用域的引用存在即可。

4、闭包的表现形式

        1、返回函数;

        2、作为函数参数传递

        3、回调函数

        4、立即执行函数

5、通过定时器循环输出自增的数字如何实现

        

for (var index = 0; index < 5; index++) {
    setTimeout(() => {
        console.log(index)
    })
}

以上代码输出结果

5
5
5
5
5

为什么呢?

第一点:因为为宏任务,由于js中单线程eventLoop机制,在主线程执行完同步任务后才会去执行宏任务,因此setTimeout循环结束后才会依次执行setTimeout中的回调。

第二点:因为setTimeout函数也是一个闭包,往上找他的父级作用域就是window,变量i为window上的全局变量,开始执行setTimeout之前变量i已经就是5了,因此最后输出连续的都是5。

那如何顺序输出0到4呢?

方案一、通过立即执行函数,创建闭包

       

for (var index = 0; index < 5; index++) {
    ((i) => {
        setTimeout(() => {
            console.log(i)
        })
    })(index);
}

方案二、用let关键字定义变量

for (let index = 0; index < 5; index++) {
    setTimeout(() => {
        console.log(index)
    })
}

方案三、传入setTimeout第三个参数(传递给函数指定的函数的附加参数)

for (let index = 0; index < 5; index++) {
    setTimeout((i) => {
        console.log(i)
    },0,index)
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值