目录

🥯 ES6 的变量与常量

ES6 新增两个重要的关键字 letconst

# let

区别 letvar

  • let 在代码块内有效, var 在全局范围内有效;
  • let 只能声明一次, var 可以声明多次;
{
  let a = 0;
  a
  var b = 1;
}
a // error: a is not defined
b // 1
1
2
3
4
5
6
7
let a = 1;
let a = 1;
a // Identifier 'a' has already been declared
1
2
3

🧮 在 for 循环计数中:

for (var i = 0; i < 10; i++) {
  setTimeout(function(){
    console.log(i);
  })
}
// 输出十个 10

for (let j = 0; j < 10; j++) {
  setTimeout(function(){
    console.log(j);
  })
}
// 输出 0123456789
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 当使用 var 进行声明时, i 在全局范围有效,所以只有一个变量 i ,循环里的十个 setTimeout 是在循环结束之后才执行,所以 i 都为 10;
  • 当使用 let 进行声明时, j 只在本轮循环中有效,所以每次循环的 j 都是新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量。(JavaScript 引擎内部会记住前一个循环的值

相比于 varlet 不存在变量提升

console.log(a);  //ReferenceError: a is not defined
let a = "apple";
 
console.log(b);  //undefined
var b = "banana";
1
2
3
4
5

变量 a 用 let 声明不存在变量提升,在声明变量 a 之前,a 不存在,所以会报错。变量 b 用 var 声明存在变量提升,所以当脚本开始运行的时候,b 已经存在了,但是还没有赋值,所以会输出 undefined

var 造成变量穿透:

// let 定义的 i 只在循环内有效
for(let i = 0;i < 5;i++){
  console.log(i);
};

// var 定义的 i 全区有效:
for(var i = 0;i < 5;i++){
    console.log(i);
};
console.log("这里就是变量穿透:" + i)
1
2
3
4
5
6
7
8
9
10

# const

const 定义一个只读变量(常量),声明之后不能修改,否则报错。

const PI = Math.PI;
1

暂时性死区:

var PI = "a";
if(true){
  console.log(PI);  // ReferenceError: PI is not defined
  const PI = "3.1415926";
}
1
2
3
4
5

ES6 中规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

📢 上次更新: 2022/09/02, 10:18:16