文档章节

闭包和let块级作用域

o
 osc_w9s1w4o0
发布于 2019/03/29 20:12
字数 580
阅读 12
收藏 0

精选30+云产品,助力企业轻松上云!>>>

还是先从一个题目开始:

写一个隔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.lengtharr[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的几个特性:

  1. 只存在于块级作用域中

  2. 不存在变量提升

  3. 暂时性死区

  4. 不允许重复声明

这里我不再赘述,大家可以仔细阅读一下阮一峰老师的书。

我更感兴趣的是,在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语法并不能实现有的特性,比如暂时性死区。

完,感谢阅读。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
JS的var和let、const使用(详细讲解)

let是ES6新增的,它主要是弥补var的缺陷,你也可以把let看做var的升级版。下面我就来详细讲讲var和let的区别 var和let的区别 不同点: (1)var是全局作用域,let不是 var 和 let 声明的变量...

osc_i05nmotv
04/16
11
0
请不要再问我闭包了!

作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期。 我们首先从块级作用域和函数作用域入手来看闭包。 一、块级作用域 任何一对花括号中的语句集都属...

黎贝卡beka
2018/08/19
0
0
javascript深入理解--作用域,作用域链,闭包的面试题解

一、概要 作用域和作用域链是js中非常重要的特性,关系到理解整个js体系,闭包是对作用域的延伸,其他语言也有闭包的特性。 那什么是作用域?作用域指的是一个变量和函数的作用范围。 1、js中...

osc_w6kvmckv
2019/02/28
3
0
【译】【nodeschool】【scope-chains-closures】作用域

作用域链与闭包工作 作用域,作用域链,闭包以及垃圾回收它们有一个共同点:那就是它们通常都是手动执行的。闭包实际上是如何工作的?垃圾回收在什么时候发生?作用域链到底是什么? 通过这次...

小草先森
2018/05/14
29
0
ES6学习笔记(1)----let和const命令

参考书《ECMAScript 6入门》 http://es6.ruanyifeng.com/ let和const命令 let 总结 1.声明变量基本使用方法与var 相同 不同点 a.在代码块中使用let声明的变量只在代码块中有效,代码块外无法...

osc_qvzk8wey
2018/03/05
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux安装redis服务器和部署

Linux安装redis和部署 第一步:下载安装包 wget http://download.redis.io/releases/redis-5.0.5.tar.gz 访问https://redis.io/download 到官网进行下载。这里下载最新的5.0.5版本. 第二步:...

osc_3ytpwpyb
16分钟前
11
0
IF函数,根据条件设定输入内容

if函数通常用于条件判断,根据判断结果执行相应命令。 1.函数解释: IF(logical_test, [value_if_true], [value_if_false]) logical_test 必需。 计算结果为 TRUE 或 FALSE 的任何值或表达式...

osc_sumf8h95
18分钟前
5
0
Pytorch自定义dataloader以及在迭代过程中返回image的name

pytorch官方给的加载数据的方式是已经定义好的dataset以及loader,如何加载自己本地的图片以及label? 形如数据格式为 image1 label1 image2 label2 ... imagen labeln 实验中我采用的数据的...

osc_l8u38961
19分钟前
6
0
灯塔

\[love\ and \ share \] 我怎么感觉变成了好东西推荐呢?算了,本来也差不多 还没写完,想到再更 有好看玩的能不能评论一下,qwq 动漫 大多是些国漫,多在\(b\)站、腾讯视频、盗版小网站能够...

osc_dc6pbw3x
20分钟前
0
0
网易首页 」 网易手机 」 正文 苹果超薄触摸显示技术专利曝光:重新定义轻薄

最近,苹果公司的新屏幕专利技术已经曝光。特别是苹果公司的新型超薄触摸技术,它可以降低显示器的结构水平,消除多余的电路,并使屏幕更薄。该专利表明,这项新技术适用于iPhone,iPad,App...

osc_opzpp18v
22分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部