文章目录
ES6常见的相关问题
1、var、let、const之间的区别
1、var
在ES5中,顶层对象(window对象)和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量
顶层对象,在浏览器环境指的是window对象,在Node指的是global对象
var a = 10;
console.log(window.a) //10
console.log(a) //10
注意点1、变量提升
var声明变量存在变量提升
console.log(a);//
var a = 20
原因
编译阶段,编译器会变成以下执行
var a
console.log(a) //undefined
a = 20
注意点2、块级作用域
在函数中使用var声明变量的时候,该变量是局部的
var a = 20
function change(){
var a = 30 //函数内部,var声明为局部变量
}
change()
console.log(a) //20
如果,没有使用var声明,该变量为全局的
var a = 20
function change(){
a = 30 //函数内部,没有使用var声明为全局变量
}
change()
console.log(a) //30
注意点3、重复声明
var声明变量时,对一个变量进行多次声明,后面的变量会覆盖前面的变量
var a = 20;
var a = 30;
console.log(a) //30
2、let (ES6)
ES6新增的命令,用来声明变量
注意点1、变量提升(不存在)
let不存在变量提升问题
console.log(a);
let a = 2;//Uncaught ReferenceError: Cannot access 'a' before initialization
ReferenceError,“引用”
注意点2、块级作用域
块级作用域中,存在let命令,这个区域就不受外部影响
在函数中使用var声明变量的时候,该变量是局部的
let a = 20
function change(){
let a = 30 /
}
change()
console.log(a) //20
注意点3、重复声明
在相同作用域中重复声明,会报错
let a = 20;
let a = 30;//Uncaught SyntaxError: Identifier 'a' has already been declared
不同作用域中重复声明,不会报错
let a = 20;
{
let a = 30;
}
declared,“声明”
注意点4、暂时性死亡
使用let声明变量前,该变量都不可用,也就是大家常说的“暂时性死区”
a = "abc";//Uncaught ReferenceError: Cannot access 'a' before initialization
let a ;
不能在函数内部重复声明参数
function func(params){
let params //Uncaught SyntaxError: Identifier 'params' has already been declared
}
3、const (ES6)
const声明的是一个只读的常量,一旦声明,常量的值就不能改变。
const a = 20;
a = 30;//Uncaught SyntaxError: Identifier 'a' has already been declared
const一旦声明变量,就必须立即初始化,不能留到以后赋值
const a //Uncaught SyntaxError: Missing initializer in const declaration
之前用var或let声明过变量,再用const声明同样会报错
var a = 20
let b = 20
const a = 30 //Uncaught SyntaxError: Identifier 'a' has already been declared
const b = 30 //Uncaught SyntaxError: Identifier 'b' has already been declared
注意
const本质上,保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据(对象、数组)不得改动
对于简单数据(数值、字符串、布尔值),变量指向的内存地址,保存的是一个值,因此等同于变量
const a = 20;
console.log(a);
a = 30;//Uncaught TypeError: Assignment to constant variable.
对于复杂数据(对象、数组),变量指向的内存地址,保存的是一个指针,const 只能const 只能保证这个指针是固定的,里面的数据结构不受控制
const a = {};
a.name = "王五"
console.log(a.name)//王五
a = {} //Uncaught TypeError: Assignment to constant variable.
const b = [];
b.push(1,2,3)
console.log(b)//[1, 2, 3]
b=[2]//Uncaught TypeError: Assignment to constant variable.
常量a 储存的是一个地址,这个地址指向一个对象/数组。不可变的只是这个地址,但对象/数组本身是可变的,所以依然可以为其添加新属性
4、总结
1、变量提升
var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
// var
console.log(a) // undefined
var a = 10
// let
console.log(b) //Uncaught ReferenceError: Cannot access 'a' before initialization
let b = 10
// const
console.log(c) //Uncaught ReferenceError: Cannot access 'a' before initialization
const c = 10
2、暂时性死区
使用 let / const 声明变量前,该变量都不可用,只有等到声明变量的那一行代码出现,才可以获取和使用该变量,也就是大家常说的“暂时性死区”
// var
console.log(a) // undefined
var a = 10
// let
console.log(b) //Uncaught ReferenceError: Cannot access 'a' before initialization
let b = 10
// const
console.log(c) //Uncaught ReferenceError: Cannot access 'a' before initialization
const c = 10
3、块级作用域
var 不存在块级作用域
let 和 const 存在块级作用域
//var
{
var a = 20;
}
console.log(a) //20
//let
{
let b = 20;
}
console.log(b) //Uncaught ReferenceError: b is not defined
//const
{
const c = 20;
}
console.log(c) //Uncaught ReferenceError: c is not defined
4、重复声明
var 允许重复声明变量
let 和 const 在同一作用域不允许重复声明变量
// var
var a = 10
var a = 20 // 20
// let
let b = 10
let b = 20 // Identifier 'b' has already been declared
// const
const c = 10
const c = 20 // Identifier 'c' has already been declared
5、修改声明的变量
var 和 let 可以修改声明的变量
const 声明一个只读的常量。一旦声明,常量的值就不能改变
// var
var a = 10
a = 20
console.log(a) // 20
//let
let b = 10
b = 20
console.log(b) // 20
// const
const c = 10
c = 20
console.log(c) // Uncaught TypeError: Assignment to constant variable
使用
能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var