ES6新增加了 let 和 const 两个关键字。let声明的变量只会在 let 命令所在的代码块中有效,coonst 声明的一个常量,一旦声明,常量的值机不能改变。
ES6 后的三大作用域
在ES6之前,JS中只存在 全局作用域和局部作用域。SE6增加了块级作用域。所以 SE6中存在 三种作用域 全局作用域,局部作用域 块级作用域
这三种作用域范围如下:
使用 var 关键字声明的变量具有 全局作用域或者局部作用域 但是不具备 块级作用域,只有使用 let 关键字声明的变量才具有块级作用域
// 全局作用域
var carName = "Volvo";
// 这里可以使用 carName 变量
function myFunction() {
// 这里也可以使用 carName 变量
}
// 局部作用域
// 这里不能使用 carName 变量
function myFunction() {
var carName = "Volvo";
// 这里可以使用 carName 变量
}
// 这里不能使用 carName 变量
// 块级作用域
{
let x = 2;
}
// 这里不能使用 x 变量
Var 和 let 关键字的区别
- let关键字声明的变量存在块级作用域,而var声明的变量不存在块级作用域
- var关键字声明的变量属于 window对象,而let 关键字声明的变量不属于window对象
- var声明的变量在任何地方都可以重新声明赋值, 而let 关键字声明的变量在不同作用域,或不同块级作用域中是可以重新声明赋值的:,但不能在同一作用域中重新声明赋值
- var 声明的变量可以 变量提升,而let声明的变量则不行。
使用 var 关键字重新声明变量时可能会带来问题,比如在块内重新声明变量后悔影响到块外的变量
var x = 20;
console.log(x); //20
{
var x = 2;
console.log(x); //2
}
console.log(x); //2
使用let 关键字重新声明变量后,本意避免此问题的发生
let y = 5;
console.log(y); //5
{
let y = 10;
console.log(y); //10
}
console.log(y); //5
let 定义的变量会区分全局 和块级作用域中变量的值而 var定义的关键字不会。
循环作用域
使用声明后的变量作为循环的条件时,var关键字声明的变量的值会随着循环条件改变而改变,而 let 关键字声明的变量的值,由于存在块级作用域,循环内的变量值和循环外的变量值不会被重新改变
var i = 5;
for(var i =0;i<10;i++){
}
console.log(i); //10
let j = 5;
for(let j = 0;j<10;j++){
}
console.log(j); //5
由于 let 声明的关键字具有块级作用域 ,所以可以认为 for循环中的 j 与 for循环外的 j 不是同一个变量
局部变零与全局变量
在函数体中使用 var 和 let 关键字声明的变量类似,都属于局部变量
// 使用 var
function myFunction() {
var carName = "Volvo"; // 局部作用域
}
// 使用 let
function myFunction() {
let carName = "Volvo"; // 局部作用域
}
由于javas中的全局作用域针对 javas环境,在HTML中全局作用域针对的时 window对象,使用var 关键字声明声明的全局作用域变量属于window对象,而使用 let 关键字声明的作用域不属于window对象.
var carName = "Volvo";
// 可以使用 window.carName 访问变量
let carName = "Volvo";
// 不能使用 window.carName 访问变量
重置变量
使用 var 关键字声明的变量在任何地方都可以修改:
var x = 2; // x 为 2
var x = 3; // 现在 x 为 3
在相同的作用域或块级作用域中,不能使用 let 关键字来重置 var 关键字声明的变量:
var x = 2; // 合法
let x = 3; // 不合法
{
var x = 4; // 合法
let x = 5 // 不合法
}
在相同的作用域或块级作用域中,不能使用 let 关键字来重置 let 关键字声明的变量:
let x = 2; // 合法
let x = 3; // 不合法
{
let x = 4; // 合法
let x = 5; // 不合法
}
在相同的作用域或块级作用域中,不能使用 var 关键字来重置 let 关键字声明的变量:
let x = 2; // 合法
var x = 3; // 不合法
{
let x = 4; // 合法
var x = 5; // 不合法
}
let 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
let x = 2; // 合法
{
let x = 3; // 合法
}
{
let x = 4; // 合法
}
变量提升
JavaScript 中var定义的关键字可以线使用,在声明,而let 定义的关键字不可以这样操作
console.log(carName);
var carName = 'BOM'
//console.log(musicName) // 不可以使用 musicName 变量
let musicName = 'happy new year'
const关键字
const 用于声明一个或多个常量,声明时必须进行初始化,且初始化后值不可再修改:
const PI = 3.141592653589793;
PI = 3.14; // 报错
PI = PI + 10; // 报错
const
定义常量与使用let
定义的变量相似:
- 二者都是块级作用域
- 都不能和它所在作用域内的其他变量或函数拥有相同的名称
两者还有以下两点区别:
const
声明的常量必须初始化,而let
声明的变量不用- const 定义常量的值不能通过再赋值修改,也不能再次声明。而 let 定义的变量值可以修改。
const关键字定义的值并非真正的常量
const 的本质: const 定义的变量并非常量,并非不可变,它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错:
// 创建常量对象
const car = {type:"Fiat", model:"500", color:"white"};
// 修改属性:
car.color = "red";
// 添加属性
car.owner = "Johnson";
但是我们不能对常量对象重新赋值:
const car = {type:"Fiat", model:"500", color:"white"}; car = {type:"Volvo", model:"EX60", color:"red"}; // 错误
const 关键字定义的变量则不可以在使用后声明,也就是变量需要先声明再使用。