本系列是针对于阮一峰大佬的文章进行简化,更方便的让大家学习阅读


前言:

我们在ES5都使用​​var​​​来声明常量跟变量,ES6使用了最新的语法,使用​​let​​​跟​​const​​分别声明。

一、let命令:

let命令是用于​声明变量​

块级作用域

1、

{
let a = 10;
var b = 10;
}
console.log(a); // ReferenceError: a is not defined.
console.log(b); // 10

a未定义,是因为let只是在它所在的块作用域执行。{}为块作用域。而b没有影响。

2、

for (let i = 0; i < 3; i++) { 
let i='abc' ;
console.log(i);
}

会打印三个abc,因为循环条件上i是使用let定义的,循环体内的i也是let定义的。这两处的i处在各自独立的作用域里,互不影响。

for (var i = 0; i < 3; i++) { 
var i='abc' ;
console.log(i);
}

而这个用var声明的只打印一次abc,是因为这个循环体里的i跟外部的i是存在于同一个作用域,相当于在全局定义了一次i。

for (var  i = 0; i < 3; i++) { 
let i='abc' ;
console.log(i);
}

这里我在内部使用let声明的,虽然外部是用var声明的,但是这样也把两个变量划分成了两个不同的作用域。同样打印出三次abc。

3、

var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10

我们先来看这个,这个大家肯定很熟悉,​​a[6]​​​输出的是​​10​​​。是因为变量​​i​​​是​​var​​​命令声明的,在全局范围内都有效。​​a[i]​​​中的​​i​​​和​​console.log(i)​​​都是指向全局变量的​​i​​​。所以​​a[6]​​​输出的是循环后最后一轮的值。不管​​a[i]​​​中​​i​​​取得什么值,都会输出的是​​10​​,

var a = [];
var i;
for (i = 0; i < 10; i++) {
a[i]=function () { console.log(i); };
}
a[6](); // 10

就相当于在上面的代码,在全局声明一个​​i​​,

var a = [];
var j;
for (i = 0; i < 10; i++) {
a[j]=function () { console.log(i); };
}
a[j](); // 10

一定要记住调用的一定是具体的值或者变量。

var a = [];
var i;
for (i = 0; i < 10; i++) {
a[i]=function () { console.log(i); };
}
a[i](); // Uncaught TypeError: a[i] is not a function

比如像这样,就报错了。

不存在变量提升

1、

console.log(i); // undefined
var i = 0

当使用​​var​​声明的话,是存在变量提升的。即变量在定义之前可以使用,只是没有定义罢了。

console.log(i); // Uncaught ReferenceError: Cannot access 'i' before initialization
let i = 0

当使用​​let​​声明的时候,不存在变量提升。打印会出现错误,这样非常好,避免了我们犯下不必要的错误。

暂时性死区

1、

我们来结合块级作用域与不允许变量提升提出了暂时性死区的概念。

if (true) {
i = 'i'; // ReferenceError
let i;
}

​{}​​中包裹的就是块级作用域,而​​i​​在没有​​let​​声明之前不能赋值,在没有​​let​​声明之前这块区域被叫做暂时性死区。

这里​​let​​有暂时性死区,​​const​​同样有。

不允许重复声明

1、

function a() {
var i = 0;
var i = 1;
}

我们在函数作用域内可以重复声明变量,不报错。

function a() {
var i = 0;
let i = 1; // Uncaught SyntaxError: Identifier 'i' has already been declared
}

但是我们用​​let​​​声明的时候就会报错。不论​​let​​​在​​var​​之后还是之前都会报错。

2、

function a(b) {
var b = 1;
console.log(b);
}
a(2) // 1

我们之前使用​​var​​我们可以重复定义参数。

function a(b) {
let b = 1;
console.log(b);
}
a(2) // Uncaught SyntaxError: Identifier 'b' has already been declared

但是我们使用​​let​​重新定义参数的时候就不行哦!

二、const命令

const声明一个只读的​常量​。一旦声明,常量的值就不能改变。

1、

const a = '我是常量,不能再定义我喽'
a = 1; // Uncaught TypeError: Assignment to constant variable.

这里我们看到我们再定义的时候就会报错。

2、

const a = {};
a.name='maomin';
a.age='23';
console.log(a); // {name: "maomin", age: "23"}

上面的代码可以执行。

const a = {};
a.name='maomin';
a.age='23';
console.log(a); // {name: "maomin", age: "23"}
a={} // Uncaught TypeError: Assignment to constant variable.

但是只要再重新定义的话,就会报错,所以在使用​​const​​声明常量的时候一定要注意这点。

const a = [];
a.push('1');
console.log(a); // ['1']
a.length = 0;
console.log(a); // []
a = ['2']; // index.html:18 Uncaught TypeError: Assignment to constant variable.

同样数组也是如此。

结语:

下面我总结下:

特性

var

let

const

变量提升

true

false

false

全局变量

true

false

false

重复声明

true

false

false

重复赋值

true

true

false

暂时性死区

false

true

true

块级作用域

false

true

true

只声明不初始化

true

true

false


谢谢浏览哦!欢迎浏览下一章。前端的路上我们一起努力