let关键字
ES6中新增的用于声明变量的关键字
作用:可以防止循环变量变成全局变量
let声明的变量只在所处于的块级有效
(一对大括号为一个块级作用域)
if (true) {
let a = 7;
}
//在块级以外访问变量a
console.log(a);
结果为: a is not defined
使用let关键字声明的变量才有块级作用域,使用var声明的变量不具有块级作用域特性
let声明的变量不存在变量提升
console.log(a);
let a = 7;
结果为: Cannot access ‘a’ before initialization
let声明的变量具有暂时性死区的特性
(在块级声明的变量变量会被绑定在块级作用域内,不受外部代码影响)
var tmp = 123;
if (true) {
//不会查找外部的tmp 依然报错 tmp 未定义
console.log(tmp);
//tmp与块级绑定 与外部tmp没有关系
let tmp = 7;
}
经典面试题
var arr = [];
for(var i = 0; i < 2; i++){
arr[i] = function(){
console.log(i);
}
}
arr[0]();//输出2
arr[1]();//输出2
分析: var声明的i为全局变量,当调用函数时,循环已执行完毕跳出 —— i=2 ,函数执行输出的是全局作用域下i的值:2
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();//输出0
arr[1]();//输出1
分析: let声明的i为块级作用域,每次循环都会产生一个块级作用域,所以函数执行时需要去自己分别对应的块级作用域中寻找i的值
const关键字
作用:声明常量,常量就是值(内存地址)不能变化的量
具有块级作用域
if(true){
const a = 7;
}
console.log(a);
结果为:a is not defined
声明常量时必须赋值
const tmp;
报错:Missing initializer in const declaration
常量赋值后,值不能修改
const tmp = 7;
tmp = 8;
报错:Assignment to constant variable.
const arr = [7,8];
arr[0] = 'a';
arr[1] = 'b';
//没有改变内存地址,所以修改成功
console.log(arr);//['a','b']
//报错
arr = ['a','b'];//Assignment to constant variable.
var、let、const区别
- 使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。
- 使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
- 使用const声明的是常量,在后面出现的代码中不能再修改该常量的值
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |