ES6中块作用域之于for语句是怎样的?
在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语句是怎样的?的更多相关文章
- ES6 学习笔记之一 块作用域与let和const
---恢复内容开始--- 在学习ES6的块作用域和 let.const 之前,我们先来看看ES5以前的 var 关键字. var 关键字用于定义一个变量,通常我们会将其与变量的赋值合并为一条语句,就像 ...
- ES6 学习笔记之二 块作用域与闭包
"闭包是函数和声明该函数的词法环境的组合." 这是MDN上对闭包的定义. <JavaScript高级程序设计>中则是这样定义的:闭包是指有权访问另一个函数作用域中的变量 ...
- ES6 中 let 和 const 总结
目录 let const 1. let要好好用 1. 基本用法 2. let声明的变量不存在变量提升 3. TDZ(temporal dead zone)暂时性死区 4. 不允许重复声明 2. 块级作 ...
- ES6中let和闭包
在开始本文之前我们先来看一段代码 for(var i=0;i<10;i++){ arr[i]=function(){ return i; } } console.log(arr[3]());// ...
- ES6(块级作用域)
我们都知道在javascript里是没有块级作用域的,而ES6添加了块级作用域,块级作用域能带来什么好处呢?为什么会添加这个功能呢?那就得了解ES5没有块级作用域时出现了哪些问题. ES5在没有块级作 ...
- ES6之块级作用域
一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1. 全局作用域: 2. 函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...
- Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)
一.js中的词法作用域和动态作用域 词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了. js中其实只有词法作用域,并没有动态作用域,this的执 ...
- Java 中 try、catch、finally 语句块的执行顺序
假设代码顺序书写如下:try → catch → finally → 其他代码 则: 1.正常执行顺序:try → catch → finally → 其他代码 2.try,catch和finally ...
- 理解JavaScript中的作用域和上下文
JavaScript对于作用域(Scope)和上下文(Context)的实现是这门语言的一个非常独到的地方,部分归功于其独特的灵活性. 函数可以接收不同的的上下文和作用域.这些概念为JavaScrip ...
随机推荐
- adnroid 监听软键盘的显隐
首先注明出处,我只是想做个笔记:http://www.jb51.net/article/64820.htm 第一眼看到的时候,觉得不太可靠,因为之前都是看到这样处理的,根据监听一个根布局的size,可 ...
- 增量处理属性之记录模式(Record Modes)
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 关闭dialog(lhgdialog)
W.$.dialog({id:'dyj'}).close(); 成功 $("#id").dialog('close');frameElement.api.close();
- 关于java序列化中的一个细节
java序列化机制的可以参考很多资料了,最近在看的时候发现了一些问题. 1. 默认的序列化机制,很多书里讲到序列化类只序列化类名,实例变量,不会实例化类变量(static)和瞬态变量(transien ...
- java.lang.Comparable<T> 接口
package java.lang; import java.util.*; public interface Comparable<T> { public int compareTo(T ...
- CentOS7 安装MongoDB 3.0服务器
1,下载&安装 MongoDB 3.0 正式版本发布!这标志着 MongoDB 数据库进入了一个全新的发展阶段,提供强大.灵活而且易于管理的数据库管理系统.MongoDB宣称,3.0新版本不只 ...
- MySQL学习记录--操作时间数据
1.返回日期的时间函数 date_add() : 可以为指定日期增加/减少任意一段时间间隔.下面举例将当前日期增加一个月和减少一个月 mysql month) as add_one_month; +- ...
- sql server sql语句导入数据到execl2007中
insert into OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 12.0;Database=C:\c.xlsx','select 字段1,字段2 FR ...
- ArcGIS操作Excel文件没有注册类解决办法
在ArcGIS Desktop中进行表连接时选择了一张excel表,但添加该表时报错: 原因是机器上缺少Office的数据驱动. ArcGIS 支持 : Excel 2003 以及更早版本的 .xls ...
- cocoapods Analyzing dependencies 问题的解决方案
pod install --verbose --no-repo-update pod update --verbose --no-repo-update 修改就ok了