关于更多es6建议去看阮一峰的博客~
es6入门:http://es6.ruanyifeng.com/
源码仓库:https://github.com/ruanyf/es6tutorial
let介绍
一.块级作用域(重点)。
我们知道,在javascript中只有全局作用域和函数作用域,并不存在块级作用域。这样,在使用时就会出现一些问题。 下面我们先来举例说明let块级作用域的使用。
例:
代码如下所示:
{ var a=5; let b=10; } console.log(a); console.log(b);
我们在控制台得到的结果如下所示:
也就是说,var声明的变量由于不存在块级作用域所以可以在全局环境中调用,而let声明的变量由于存在块级作用域所以不能在全局环境中调用。
二.不存在变量提升
var定义变量:可以先使用,后声明;而let定义变量:只可先声明,后使用。
例:
var num1=100; console.log(num1); let num2=200; console.log(num2); console.log(i); var i=10; console.log(j); let j=5;
我们可以看到结果如下:
即前两个都是先声明后使用,没有问题。而后两个都是先使用,后声明,用var 声明的显示undefined,而 let声明的直接报错。
说明:console.log(i);
var i=10;
实际上相当于:
var i;
console.log(i);
i=10;
所以会出现undefined的情况。
三.暂时性死区
暂时性死区即:只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
例5:
var tmp=123; if(true){ tmp="abc"; let tmp; }
结果如下:
也就是说:虽然上面的代码中存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定了块级作用域,所以在let声明变量前,对tmp赋值会报错。此即暂时性死区。
注意:ES6规定暂时性死区和不存在变量提升就是为了减少运行时的错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
暂时性死区就是: 只要块级作用域内存在let,那么他所声明的变量就绑定了这个区域,不再受外部的影响。
暂时性死区即 Temperary Dead Zone,即TDZ。
注意:暂时性死区也意味着 typeof 不再是一个百分之百安全的操作。 如下:
if (true) { console.log(typeof x); let x; }
这里如果没有let x,那么typeof x的结果是 undefined,但是如果使用了let x,因为let不存在变量提升,所以这里形成了暂时性死区,即typeof x也是会报错的。。。 从这里可以理解暂时性死区实际上就是这一部分是有问题的 。
四.不允许重复声明
function func (){ let b=100; var b=10; } function add(num){ let num; return num+1; } function another(){ let a=10; let a=5; }
上述三个得到的结果均为:
只是前两者为 b和num被声明过了。注意:第二个函数,虽然我们没有明确的声明,但是参数实际上是相当于用var声明的局部变量。
let应用
- 因为闭包的存在,会给我们的应用中带来一些不必要的麻烦。比如下面的例子:
<body> <input type="button" value="按钮1" > <input type="button" value="按钮2" > <input type="button" value="按钮3" > <script type="text/javascript"> var btns = document.getElementsByTagName("input"); for (var i = 0; i < 3; i++) { btns[i].onclick = function () { alert("我是第" + (i + 1) + "个按钮"); }; } </script> </body>
在实际点击button的时候,弹出的都是”我是第4个按钮”,这又是为什么呢?是因为闭包导致的,给onclick赋值的函数内部已经访问了另一个外部作用域的变量i,而闭包中使用的局部变量的值,一定是局部变量的最后的值。因此点击的时候,总是会读取i的最后一个值3,因此造成了每次点击都是“第4个按钮”。
-
遇到这种问题,有三种解决方式供参考。
- 方式1:给每个按钮添加一个属性,来保存每次i的临时值。
<body> <input type="button" value="按钮1" > <input type="button" value="按钮2" > <input type="button" value="按钮3" > <script type="text/javascript"> var btns = document.getElementsByTagName("input"); for (var i = 0; i < 3; i++) { //把i的值绑定到按钮的一个属性上,那么以后i的值就和index的值没有关系了。 btns[i].index = i; btns[i].onclick = function () { alert("我是第" + (this.index + 1) + "个按钮"); }; } </script> </body>
- 方式2:使用匿名函数的自执行
<body> <input type="button" value="按钮1" > <input type="button" value="按钮2" > <input type="button" value="按钮3" > <script type="text/javascript"> var btns = document.getElementsByTagName("input"); for (var i = 0; i < 3; i++) { //因为匿名函数已经执行了,所以会把 i 的值传入到num中,注意是i的值,所以num (function (num) { btns[i].onclick = function () { alert("我是第" + (num + 1) + "个按钮"); } })(i); } </script> </body>
方式3:使用es6新增的let声明变量i
<body> <input type="button" value="按钮1" > <input type="button" value="按钮2" > <input type="button" value="按钮3" > <script type="text/javascript"> var btns = document.getElementsByTagName("input"); for (let i = 0; i < 3; i++) { btns[i].onclick = function () { alert("我是第" + (i + 1) + "个按钮"); }; } </script> </body>