ES6学习笔记(一)let和const

let是ES6中新加入的变量声明,和var类似,但是let声明的变量只能在块级作用域中使用

if(true){
    var a=1; 
}
console.log(a);//输出1


if(true){
    let b=1;
}
console.log(b);//报错:Uncaught ReferenceError: b is not defined

在这里a通过var在if块中声明,声明后在if块外面仍能调用,但是let在if块中声明后在块外面调用时却报了变量未声明的错误,这是因为let声明的变量只能在其所在块级作用域中使用。使用for循环时也是一样:

a = [];
for (var i = 0; i < 5; i++) {
    a[i] = () => console.log(i);
}
a[3]();//5



a = [];
for (let i = 0; i < 5; i++) {
    a[i] = () => console.log(i);
}
a[3]();//3

在使用var时,因为i为全局变量,所以在每次循环的时候,i的值都会发生变化,即每次赋给console.log(i)中的i的值是一样的,也即是最后一次循环结束时的值。

而在使用let时,因为其声明的变量会在块级作用域中,所以每次i都是对应我们所要打印出来的值,除此之外,在使用for循环时使用let来声明要用于循环的变量,可以使该变量在循环结束后消除该变量。


在平时使用var时,我们会遇到一个奇怪的现象,即变量在声明之前就可以使用,即我们平常所说的变量提升

a=1;
var a;//1

在ES6中,let并没有这种奇怪的特性,看起来更为规范,当我们在用let声明前使用了该变量,会发生报错

a=1;
let a;// Uncaught ReferenceError: a is not defined

由于let没有变量提升,所以出现了暂时性死区,即在一个块级作用域中,如果let声明了一个变量,这个变量就会受其“绑定”,不受外部作用域影响,在该块级作用域中如果用let声明了一个变量,那么在这个块级作用域中在这个声明之前就不能使用该变量,即使在外部的作用域中已声明了该变量。

var a=1;
if(true){
    a++;
    let a;
}
//Uncaught ReferenceError: a is not defined

在上面这段代码中,虽然a已经被声明为全局变量,但因为在if后的块级作用域中,用了let声明变量a,但是却又在该声明前使用了a,所以报错了。

除此之外,let在同一作用域中也不能重复声明,也不能重新声明函数传进来的参数

if(true){
    let a=1;
    let a=2;
}
//Uncaught SyntaxError: Identifier 'a' has already been declared

function func(a) {
    let a;
}
func(1);
//Uncaught SyntaxError: Identifier 'a' has already been declared

function func(a) {
    {let a;}
}
func(1);
//undefined  (不报错)

const声明一个只读的常量,声明之后不能对其进行修改,出于这个特性,const在声明时就要赋值,如果在之后赋值会报错,其作用域与let一样,都是块级作用域,不存在变量提升,也会有暂时性死区。

const a=1;
a=2;//Uncaught TypeError: Assignment to constant variable.

const a;
a=1;//Uncaught SyntaxError: Missing initializer in const declaration

事实上const声明的变量也并非值不能改变,在阮一峰的ECMAScript 6入门中有说到

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

参考文档:阮一峰的《ECMAScript 6入门》

猜你喜欢

转载自blog.csdn.net/zemprogram/article/details/84371671