let&const
let和const命令是ES6中新增的用来声明变量的命令。
let命令
let用法与 var 类似,但是 let 声明的变量只在它所在的代码块有效。ES6 let命令实际上为 Javascript 新增了块级作用域。ES5提供了全局作用域和函数作用域,没有块级作用域。
1 | { |
当有了块级作用域后:
1 | let name = 'es6'; |
注意:
- let声明的变量不存在变量提升。所以使用let变量前,必须先声明,否则会报错。*
暂时性死区:ES6明确规定,如果区块中存在let和const声明的变量,从一开始就形成了封闭作用域。在变量声明之前调用这下变量会报错。
1 | var tmp = 123; |
- 不允许重复声明:let 不允许在相同作用域内,重复声明同一变量。*
const
const声明一个只读的常量,一旦常量声明,就不能改变。如果尝试修改const变量值,就会报错。同时,const一旦声明变量,就必须立即进行初始化,只声明不赋值,同样会报错。
const变量不存在变量提升。与let类似,const变量只在声明所在块级作用域有效,存在暂时性死区,不能重复声明。
1 | const m = 1; |
Tips:
当引用第三方库时声明的变量,用const来声明,可避免重命名导致的bug
const 命令声明的常量,也不能提升,同样存在暂时性死区,只能在声明的位置后使用。
2017-11-10 补充:
本质
const 实际上保证的,并不是变量的值不改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值,字符串,布尔值),值就保存在变量指向的那个内存地址,因为等同于常量。但对于复合类型的数据(主要是数组和对象),变量指向的那个内存地址,保存的就是一个指针,const只能保证这个指针是固定,至于它指向的数据结构是不是可变的,就完全不能控制了。
1 | const foo = {} |
上述代码中,常量foo储存一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本上是可变的,所以依然可以为其添加新属性。
1 | const a = []; |
上面代码中,常量a是个数组,数组本身是可写的,但是如果将另一个数组赋值给a, 就会报错。
如果想冻结对象,使用Object.freeze方法
1 | const foo = Object.freeze({}) |