在ES6中新加了快作用域的概念(C语言就有,作为类c语言的js,当然应该加上),算是很好理解。

{
let i;
}
console.log(i);// i is not defined

在代码块当中使用新的作用域。

问题在于for语句

let arr=[];
for(let i=0;i<5;i++){
arr[i]=function(){
console.log(i);
};
}

许多的讲解并没有特别说明它的作用域是怎么看的,似乎是自然而然的事情。

然而对于以前c没专心学,真正会的也就类似PHP,javascript的无块作用域的孩子就觉得疑惑了。

我的错误理解1:

let arr = [];
(function(){//作用域直接包含整个for循环?wrong
for (var i = 0; i < 5; i++) {
arr[i] = function () {
console.log(i);
};
}
})();

我的错误理解2:

let arr = [];
for (var i = 0; i < 5; i++) {
(function () {//作用域包含单次循环?wrong
arr[i] = function () {
console.log(i);
};
})();
}

测试结果都说明自己的理解是有误的,找资料的时候,这里都一笔被带过了(可能因为各位作者都用过块作用域的吧)。

于是想到babel既然是ES6转ES5,理解是正确的,那么可以找它帮忙。

方法,使用babel转码加深特性的理解,

直接在线转码

转码前:

let arr=[];
for(let i=0;i<5;i++){
arr[i]=function(){
console.log(i);
};
i++;
}
console.log(i);//i is undefined
arr[0]();

转码后:

"use strict";

var arr = [];

var _loop = function _loop(_i2) {
arr[_i2] = function () {
console.log(_i2);
};
_i2++;
_i = _i2;
}; for (var _i = 0; _i < 5; _i++) {
_loop(_i);
}
console.log(i); //i is undefined
arr[0]();

通过babel转码后就可以清晰的看出来了:

1、作用域是分成两部分的,在整个for循环外层相当于有一个作用域,这里babel使用变量  _i  来区别   i  变量,等价于一个作用域,在理解上可以这样理解,

let arr = [];
for (let i = 0, len = 5; i < 5; i++) {
arr[i] = function () {
console.log(i);
};
}
console.log(i);
arr[0](); "use strict"; var arr = []; var _loop = function _loop(_i) {
arr[_i] = function () {
console.log(_i);
};
};
(function () {
for (var i = 0; i < 5; i++) {
_loop(i);
}
})();
console.log(i); //i is undefined
arr[0](); "use strict"; var arr = []; (function () {//等价于for循环外层作用域,babel中使用变量别名来优化
var _loop = function _loop(_i2) {
arr[_i2] = function () {
console.log(_i2);
};
_i2++;
i = _i2;
}; for (var i = 0; i < 5; i++) {
_loop(i);
}
})();
console.log(i); //i is undefined
arr[0]();

2、每个单次循环也是一个作用域,代码中的_loop,即是用函数作用域来模拟块作用域。

3、在单次循环中注入了for语句中声明的i变量,并且在一次循环后,将i变量赋值回来(_loop代码中i=_i2)。

运行结果是一样,但是却觉得我的理解很有问题,通常越强大的规则通常是越简单的,是否有更准确的解释呢?求不吝相告

ES6中块作用域之于for语句是怎样的?的更多相关文章

  1. ES6 学习笔记之一 块作用域与let和const

    ---恢复内容开始--- 在学习ES6的块作用域和 let.const 之前,我们先来看看ES5以前的 var 关键字. var 关键字用于定义一个变量,通常我们会将其与变量的赋值合并为一条语句,就像 ...

  2. ES6 学习笔记之二 块作用域与闭包

    "闭包是函数和声明该函数的词法环境的组合." 这是MDN上对闭包的定义. <JavaScript高级程序设计>中则是这样定义的:闭包是指有权访问另一个函数作用域中的变量 ...

  3. ES6 中 let 和 const 总结

    目录 let const 1. let要好好用 1. 基本用法 2. let声明的变量不存在变量提升 3. TDZ(temporal dead zone)暂时性死区 4. 不允许重复声明 2. 块级作 ...

  4. ES6中let和闭包

    在开始本文之前我们先来看一段代码 for(var i=0;i<10;i++){ arr[i]=function(){ return i; } } console.log(arr[3]());// ...

  5. ES6(块级作用域)

    我们都知道在javascript里是没有块级作用域的,而ES6添加了块级作用域,块级作用域能带来什么好处呢?为什么会添加这个功能呢?那就得了解ES5没有块级作用域时出现了哪些问题. ES5在没有块级作 ...

  6. ES6之块级作用域

    一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1.  全局作用域: 2.  函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...

  7. Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)

    一.js中的词法作用域和动态作用域      词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了.       js中其实只有词法作用域,并没有动态作用域,this的执 ...

  8. Java 中 try、catch、finally 语句块的执行顺序

    假设代码顺序书写如下:try → catch → finally → 其他代码 则: 1.正常执行顺序:try → catch → finally → 其他代码 2.try,catch和finally ...

  9. 理解JavaScript中的作用域和上下文

    JavaScript对于作用域(Scope)和上下文(Context)的实现是这门语言的一个非常独到的地方,部分归功于其独特的灵活性. 函数可以接收不同的的上下文和作用域.这些概念为JavaScrip ...

随机推荐

  1. Eclipse 启动出现错误 no java virtual machine was found

    出现此问题的原因是eclipse找不到javaw.exe的path,打开eclipse.ini文件: -startup plugins/org.eclipse.equinox.launcher_1.3 ...

  2. property animation ( NineOldAndroid )

    区别一:需要的Anroid API level不一样 Property Animation需要Android API level 11的支持,而View Animation则是更早期的版本. 区别二: ...

  3. 一次U盘拯救的经历

    U盘拷资料,突然就弹出框框,复制终止了,然后U盘里面的只是编程可读的了. 倒是没有啥重要的资料,就是只有这一个U盘了,平时传资料都靠它,不能就这么垮了啊,于是就来了一次拯救行动. 一共有三个步骤 第一 ...

  4. Python进阶(三)--global和类属性

    global关键字 一句话概括为:告诉python解释器,global声明的变量为全局作用域内定义的变量.解释器就会到全局作用域内寻找global定义的变量. python的类属性 类属性相当于其他O ...

  5. 一个简单的物料防错DEMO

    前言 快2个月没写过博客了,就算是记流水账似的文章都没时间写,主要是太忙了:太多的bug要修复.太多由于bug引起的异常问题要解决.还有新的项目要开发,不忙怎么行呢?最近利用业余时间在鼓捣一个PDA的 ...

  6. 你的指纹还安全吗? - BlackHat 2015 黑帽大会总结 day 2

    你的指纹还安全吗?  0x03 FINGERPRINTS ON MOBILE DEVICES: ABUSING AND LEAKING speaker是来自FireEye的Wei Tao和Zhang ...

  7. python成长之路【第十四篇】:HTML初步认识

    HTML介绍 HTML是负责描述文档语义的语言.它是纯文本文件,用一些标签来描述文字的语义,这些标签在浏览器里面是看不到的,所以称为"超文本".所以就是"超文本标记语言& ...

  8. Comparator

    1.java.util.Comparator 一个实现了comparator接口的对象能够对比不同的对象.它不能用于同一个类的不同实例的对比,但是可以用于其他的类的实例做对比.必须实现java.uti ...

  9. [Java] Java解析XML格式Response后组装成Map

    //Get and Parse Response def response = context.expand(‘${TestStepName#Response}’) def xmlParser = n ...

  10. 首页自动生成静态化html

    由于平台老是出现间歇性502.排查发现,php死进程过多耗费大量系统资源. 除了优化代码之外,静态化可以减少php进程.缓解一下服务器压力. 把首页生成html后,出现问题频率下降.所以需要做首页静态 ...