一、引
准备认认真真的学习下 ES6 之前都是马马虎虎的就看一俩眼,这就准备把学习的都记录下来,所有的资料都参考于 ECMAScript 6 入门 ,一来学习一下,二来养成下写博客的习惯。那就直接开始把。
二、let
2.1 概论
在 ES6 之前,大家肯定是用 var
来定义一个变量的,但是大家都知道,它有个问题就是变量提升(不懂的可以看这里),所以在 ES6 中提供了一种更加严谨的命令 let
。let
让变量只在代码块内有效。看个例子:
{
let a = 10;
var b = 20;
}
console.log(a) //Uncaught ReferenceError: a is not defined
console.log(b) //20
当然let
肯定是弥补了 var
的缺点,不存在变量提升的,看个例子:
console.log(a); // undefined
var a = 2;
console.log(b); //Uncaught ReferenceError: b is not defined
let b = 2;
上面代码在代码块之中,分别用 let
和 var
声明了两个变量。然后在代码块之外调用这两个变量,结果 let
声明的变量报错, var
声明的变量返回了正确的值。这表明,let
声明的变量只在它所在的代码块有效。这样就可以在 for 循环中来使用这个命令同时不污染外部变量。
for (let i = 0; i < 10; i++) {
console.log(i); //0 1 2 3 4 5 6 7 8 9
}
console.log(i); //Uncaught ReferenceError: a is not defined
2.2 TDZ暂时性死区
名字好像挺高级的,但是大概的意思就是,在一个代码块内如果用 let
定义了一个变量,那么在这个代码块内的定义之前无法使用这个变量(无论之前是否被定义过),否则就会报 Uncaught ReferenceError: *** is not defined
错误。看个例子:
var a = 1;
if (true) {
a = 2; // Uncaught ReferenceError: a is not defined
let a;
}
这样看就很直观。虽然在全局作用域中已经定义了 a
,但是在 if
所形成的作用域中 a
被 let
重新定义了,所以在 if
的代码块内且 let
之前,a
是不允许被使用的。const
命令也有同样的限制,下面会讲到。
2.3 不允许重复定义
function func() {
let a = 1;
var a = 2;
}
function func() {
let a = 1;
let a = 2;
}
如果你把 let
看作一个比较严格的定义命令,那么这个也就很好理解了,let
定义的变量一定是唯一的。
二、const
3.1 概论
从意思上看也能懂,是个常量,那么一经定义,则不能再被修改
const a = 1;
console.log(a); //1
a = 2 //Uncaught TypeError: Assignment to constant variable
既然 const
是常量定义,那肯定也不可以光定义,不赋值的。
const a ; // Uncaught SyntaxError: Missing initializer in const declaration
块级作用域和TDZ和 let
一样都是存在的。在这里就不多介绍了。
3.2 本质
const
并不是让变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复杂类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const
只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。
const foo = {};
foo.prop = 123;
console.log(foo.prop); // 123
foo = {}; // TypeError: "foo" is read-only
上面代码中,常量 foo
储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把 foo
指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
const a = [];
a.push('Hello');
a.length = 0;
a = ['Dave']; // Uncaught SyntaxError: Identifier 'a' has already been declared
上面代码中,常量 a
是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。