超级干货,浅谈闭包。

一、闭包的定义

        闭包是一个函数以及周边环境状态(词法作用域)的引用组合。(画重点:闭包是函数,并且引用外部变量)换而言之,闭包可以让开发者从函数内部访问外部的函数的作用域。在JS中,闭包随着函数的创建而被创建。好处可以保护数据私有,坏处可能会影响性能,比如内存泄漏!!(注意:闭包引起的内存泄漏是不恰当使用而造成的,所以,谨慎使用闭包)

        init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName()定义在init()里的内部函数,仅在init()函数体内可用。(块级作用域)displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,(形成闭包)所以 displayName() 可以使用父函数 init() 中声明的变量 name 。

        扩展:词法,词法作用域根据源代码声明变量位置来确定变量在何处可用。嵌套函数可访问声明于他的外部作用域的变量。

二、在循环中创建闭包:一个常见的错误

        在ECMAScript 2015引入let关键字之前,在循环中有一个常见的闭包创建问题。

        运行这段代码后,你会发现它没有达到想要的效果。无论焦点在哪个 input 上,显示的都是关于年龄的信息。

        原因是赋值给 onfocus 的是闭包。这些闭包是由他们的函数定义和在 setupHelp 作用域中捕获的环境所组成的。这三个闭包在循环中被创建,但他们共享了同一个词法作用域,在这个作用域中存在一个变量 item。这是因为变量 item 使用 var 进行声明,由于变量提升,所以具有函数作用域。当 onfocus 的回调执行时,item.help 的值被决定。由于循环在事件触发之前早已执行完毕,变量对象 item(被三个闭包所共享)已经指向了 helpText 的最后一项。

        可以使用立即执行函数或者将var改成let即可解决,本质上就是每次循环都为item创建新的块级作用域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值