Babel的小bug引发的疑问:es6的let类型与闭包间的关系

let是ES6变量类型,其只在代码块内有效。

闭包是有函数以及创建该函数的词法环境组合而成,这个环境包含了这个闭包创建时所能访问的所有局部变量。

如果合理使用闭包,可以使用var实现let局部有效的效果。显然这是多余的,因为babel已经能帮我们做了,并且很多新版浏览器都支持let,所有本文结束。

等等,babel都干了啥?为啥能将let转码使代码兼容旧版浏览器?兼容转码

我们先来看一段比较简单的babel转码

我们来搬一段特别复杂的let类型申明代码

在babel官网将其转码为兼容代码:

老司机马上就看出了:将let转为了闭包闭包

我们来看看MDN上的一段例子

闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。

我们一通分析便可以看出code3闭包的基本结构:

code4的闭包是立即执行利用闭包,使var == let

code4的结构不正是code2的简写吗?我们可以将code2改写为

说好的简写呢?!

仔细阅读这句话闭包是由函数以及创建该函数的词法环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量。

let是块级作用域,也就是局部作用域。闭包也是能访问局部作用域。

code4正是将变量i赋值给函数的局部变量j,code5中数组a的每个item都是该函数实例的引用。

在let出现之前,在循环中写闭包是一个比较常见的问题。

我们不鼓励在循环中创建闭包,过多的闭包会付出性能代价。Babel的bug

意外发现了一个Babel的小bug。我们在最新的Chrome/Firefox浏览器中运行这段代码:

会发现输出结果为3次”abc 1539160907***”。将code6通过Babel转码得到code7

code7在浏览器中仅仅运行了1次,输出结果为”abc 1539160907***”

阮老师讲:for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

发表评论
留言与评论(共有 0 条评论)
   
验证码:

相关文章

推荐文章

'); })();