闭包和let块级作用域
还是先从一个题目开始:
写一个隔1s输出数组的一项的函数。
如果可以用ES6语法,则可以这么写:
function print (arr) {
for (let i = 0; i < arr.length; i++) {
setTimeout(() => {
console.log(arr[i])
}, 1000 * i);
}
}
但是如果把这里的let改成var,则输出就会变成一连串的undefined。
有同学很快想到了这是闭包啊,因为setTimeout把函数加入到microqueue中,所以等到setTimeout的函数体执行时,i已经走完了for循环,变成了arr.length。arr[arr.length]显然是undefined。
简单修改一下,变成ES5的语法。
function print (arr) {
for (var i = 0; i < arr.length; i++) {
(function (index) {
setTimeout(() => {
console.log(arr[index])
}, 1000 * index);
})(i);
}
}
其实就是利用闭包是向父级作用域寻找值的特性,给i包装一层作用域,把i存起来。
闭包概念还请翻看之前的一篇blog-闭包和类。
到这里闭包的理解应该差不多了,而今天的关键点在于——
let做了什么?
阮一峰老师的《ECMAScript 6》入门里给出[定义](http://es6.ruanyifeng.com/#docs/let:
ES6 新增了
let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
他提到了let的几个特性:
只存在于块级作用域中
不存在变量提升
暂时性死区
不允许重复声明
这里我不再赘述,大家可以仔细阅读一下阮一峰老师的书。
我更感兴趣的是,在ES5的语法中,如何模拟let这种块级作用域的效果。这个时候,应该让babel出场了。
打开这个链接:可以看到转换后的代码。
"use strict";
function print(arr) {
var _loop = function _loop(i) {
setTimeout(function () {
console.log(arr[i]);
}, 1000 * i);
};
for (var i = 0; i < arr.length; i++) {
_loop(i);
}
}
其实可以对比发现,babel转换后的代码和我们上面写的ES5实现其实是一样的。
大概就是通过对let绑定的块级作用域加一个函数,把let声明的参数,通过函数传入,达到块级作用域的效果。
大家可以在babel试一下let的其他特性,转移出的ES5语法并不能实现有的特性,比如暂时性死区。
完,感谢阅读。
闭包和let块级作用域的更多相关文章
- JavaScript函数表达式、闭包、模仿块级作用域、私有变量
函数表达式是一种非常有用的技术,使用函数表达式可以无需对函数命名,从而实现动态编程.匿名函数,是一种强大的方式,一下总结了函数表达式的特点: 1.函数表达式不同于函数声明,函数声明要求有名字,但函数表 ...
- JS 模仿块级作用域
function outputNumbers(count) { for (var i=0; i<count; i++) { console.log(i); } var i; // 重新声明变量 ...
- js中的块级作用域
概述 函数是js中最常见的作用域单元, 声明在一个函数内部的变量或函数会在所处的作用域中隐藏起来, 这是有意为之的非常好的设计原则. 但是随着js的发展, 我们有了某个代码块(通常指{..}内部)隐藏 ...
- 你不知道的JS之作用域和闭包(三)函数 vs. 块级作用域
原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到 ...
- ES6 浅谈let与const 块级作用域之封闭空间(闭包)
ES6新增了 let const 命令,用来声明变量.它的用法类似于 var ,但是所声明的变量,只在 let const 命令所在的代码块内有效. var const 不允许重复声明 用处: 可 ...
- JavaScript模仿块级作用域
avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...
- ES6之块级作用域
一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1. 全局作用域: 2. 函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...
- ES6 - Note1:块级作用域与常量
在ES6以前,ES不支持块级作用域,只有全局作用域和函数作用域,所有变量的声明都存在变量声明提升. 1.let 关键字 声明一个块级变量,只在一个代码块中有效,如果在块外面访问便会报错,如下所示: { ...
- JavaScript的作用域和块级作用域概念理解
作用域 作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期.说到这里我们需要理解两个概念:块级作用域与函数作用域. 函数作用域 这个应该好理解,函数作用域就是说定义在 ...
随机推荐
- RabbitMQ基础--总结
一. RabbitMQ的五种工作场景: 1. 单发单收 2. 单发送多接收 +++++++++++++++++++++前面两种没有使用exchange++++++++++++++++++ 3. Pub ...
- ES5 object方法整理
Object.getPrototypeOf(object):调用对象父类原型上的方法; function Person(){ this.method1 = function(){alert(1)} } ...
- JavaScript的重载(通过argument.length)
偶然间在博客园看到的关于js的重载(重载就是一组具有相同名字.不同参数列表,实现不同操作的函数或方法)问题,作为初学者,在看红宝书的时候,记得书中有概念说明js是没有重载的 所以,觉得有必要把这一段 ...
- iview table数据排序不正确
在使用iview的table组件时,要做排序 代码: sortable: true,sortMethod: (a, b, type) => { if (type === 'desc') { re ...
- Java基础_day01
一.JRE和JDK的安装, JRE —— Java 运行环境 Java runtime environment 包含Java虚拟机和Java程序的核心类库. ...
- QQ 聊天机器人小薇 1.0.1 发布!
本次发布主要解决了消息丢失(Api返回码[1202])问题,并改进了改进了一些细节. 简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动: 监听多个 Q ...
- <Android 应用 之路> 百度地图API使用(3)
前言 上一篇讲解并实践了百度地图基本显示,地图类型,实时交通图,热力图,地图控制和手势控制,今天看下在地图上添加view和覆盖物. 地图Logo不允许遮挡,可通过mBaiduMap.setPaddin ...
- 考勤机sql语句
考勤机sql语句 SELECT checkinout.id as 序号 ,checkinout.pin as 打卡编号,userinfo.name 姓名, checkinout.checktime 签 ...
- C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文
原文:http://www.cnblogs.com/JCSU/articles/1305401.html C语言字符串操作函数 1. 字符串反转 - strRev2. 字符串复制 - strcpy3. ...
- 使用spring tool suite(STS)工具创建spring boot项目和出现错误后的处理
一.先下载配置maven环境 1.下载地址:http://maven.apache.org/download.cgi windows下下载zip文件 2.解压后放到某个文件目录下 3.配置环境变量 ( ...