用法
let myName = 'luoxue';
let age = 25;
描述
let
语句允许申明一个作用域被限制在代码块内的变量、语句或表达式。
浅析
{
let myName = 'luoxue';
}
console.log(myName); // myName is not defined
之所以报错 ,是因为 let
所申明的变量只在 let
语句所在代码块内有效;
和 var
对比
1、作用域
{
let myName = 'luoxue';
var age = 25;
console.log(myName); // luoxue
}
console.log(myName); // myName is not defined
console.log(age); // 25
上面这段代码可以看到,let
的作用域是 let
语句所在代码块或者其子块,而 var
的作用域则是整个封闭函数。
2、let
不存在变量提升
console.log(color); // color is not defined
let color = 'orange';
console.log(colors); // undefined
var colors = 'yellow';
3、暂时性死区
只要块级作用域内存在 let
语句,它所申明的变量就“绑定”这个区域,不受外部的影响,如下:
var love = 'kk';
if(true) {
love = 'kkk'; // love is not defined
let love = 'k';
}
注:ES6明确规定,如果区块内存在 let
const
语句,则这个区块对这些语句申明的变量从一开始就形成封闭作用域,只要在申明之前实用,就会报错,如下也会报错:
{
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
}
暂时性死区的本质:只要一进入当前作用域,所要实用的变量就已经存在,但是不可获取,只有出现申明变量的那行代码之后,才可以获取和实用该变量。
4、不允许重复申明
{
let yourName = 'kk'; // Identifier 'yourName' has already been declared
let yourName = 'k';
}
下面的代码书写方式是不允许的:
let fn = (arg) => let arg = 25; // Unexpected identifier
运用
有一道题目如下,说明为什么 a[3]()
的结果是5,如何实现 a[3]()
的结果是3?
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语句;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。