let myName = 'luoxue'; let age = 25;
let
语句容许申明一个做用域被限制在代码块内的变量、语句或表达式。git
{ let myName = 'luoxue'; } console.log(myName); // myName is not defined
之因此报错 ,是由于 let
所申明的变量只在 let
语句所在代码块内有效;es6
var
对比{ let myName = 'luoxue'; var age = 25; console.log(myName); // luoxue } console.log(myName); // myName is not defined console.log(age); // 25
上面这段代码能够看到,let
的做用域是 let
语句所在代码块或者其子块,而 var
的做用域则是整个封闭函数。github
let
不存在变量提高console.log(color); // color is not defined let color = 'orange'; console.log(colors); // undefined var colors = 'yellow';
只要块级做用域内存在 let
语句,它所申明的变量就“绑定”这个区域,不受外部的影响,以下:闭包
var love = 'kk'; if(true) { love = 'kkk'; // love is not defined let love = 'k'; }
注:ES6明确规定,若是区块内存在 let
const
语句,则这个区块对这些语句申明的变量从一开始就造成封闭做用域,只要在申明以前实用,就会报错,以下也会报错:ide
{ title = 'Love you'; // title is not defined console.log(title); // title is not defined let title; console.log(title); // undefined title = 'Love kk'; console.log(title); // Love kk }
暂时性死区的本质:只要一进入当前做用域,所要实用的变量就已经存在,可是不可获取,只有出现申明变量的那行代码以后,才能够获取和实用该变量。函数
{ let yourName = 'kk'; // Identifier 'yourName' has already been declared let yourName = 'k'; }
下面的代码书写方式是不容许的:code
let fn = (arg) => let arg = 25; // Unexpected identifier
有一道题目以下,说明为何 a[3]()
的结果是5,如何实现 a[3]()
的结果是3?ip
var arr = []; for(var i = 0; i < 5; i++) { arr[i] = function() { console.log(i); } } arr[3](); // 5
这里的 i
是用的 var
申明的,那么 i
的做用域则是全局,当用 a[3]()
调用时 i
的值随着循环的结束已经变为5,因此 arr[3]()
的值是5,可使用 let
语句来重构一下,以下:内存
let arr = []; for(let i = 0; i < 5; i++) { arr[i] = function() { console.log(i); } } arr[3](); // 3
由于在 for
语句里面用 let
定义的 i
的做用域是 for
语句里面的代码块,因此每次循环的 i
都是一个新的变量,都互不干扰,最后执行结果也就是对应的3,固然,这里也能够实用闭包的方式来实现,代码以下:作用域
// 闭包的实现方式 var arr2 = []; for(var i = 0; i < 5; i++) { arr2[i] =(function(e) { return function() { console.log(e); } })(i); } arr2[3]();
参考:
阮一峰老师的《es6入门标准》第二章第一小节(实体书);
MDN let语句;