一.let命令
基本用法
let是在ES6标准中的新增语法,用于声明变量,类似于var命令,但是用let声明的变量,仅仅在其代码块内可以被引用,例如:
{
let a = 0 ;
var b = 1 ;
}
console.log(a); // 报错ReferenceError: a is not defined.
console.log(b); // 控制台打印出 1 .
不存在变量提升
var命令会出现变量提升现象,即变量可以在声明之前使用,值为undefined. 下面的变量a,在脚本运行的时候就已经存在,但是没有具体值,所以是undefined.
let命令则不会出现变量提升现象,由let声明的变量的特性就是,必须在声明之后使用,否则就会报错.
console.log(a) ; //输出undefined
var a = 1 ;
console.log(b) ; //报错 ReferenceError: b is not defined.
let b = 0 ;
暂时性死区
ES6语法规定, 只要块级作用域内存在let命令, 那么其所声明的变量,就绑定在这个这个区域内,不在受到外部影响. 在此区域内, 只要在其声明之前使用了该变量, 就会报错 . 这在语法上被称为 ‘‘暂时性死区’’(TDZ)
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
在上面的代码块中,在变量tmp被声明之前,都属于变量tmp的死区 …
总之就是,在作用域内, 变量只能在声明之后使用
不允许重复声明
let不允许在同一个作用域内重复声明同一个变量 .
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
二. const 命令
const 声明的常量值不能被更改.
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
这就意味着, const声明变量的同时就必须初始化 ,不能先声明 ,后赋值 .
const foo;
// SyntaxError: Missing initializer in const declaration
const作用域
const作用域与let相同 , 都是只在声明所在的块级作用域内有用 , ,同时也是没有变量提升 , 存在暂时性死区 , 不可重复声明 .
const本质
const所保证的 , 并不是变量的值不能改变 , 而是变量所指向的那个内存地址所保存的 值不能改变 .
对于简单数据而言(boolean , 字符串, 数字) , 值就保存在变量所指向的那个内存地址里 , 所以const声明的简单数据类型相当于常量 .
对于复合类型而言(对象,数组) , 变量所指向的内存地址 , 实际上保存的是一个指向真实数据的指针 , const只能保证该指针是不变的 , 而控制不了指针所指向的数据是否改变
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
常量foo保存的是地址 , 地址指向的是对象, 地址不可变, 但是对象本身可变