一直没有好好地学习ES6,最近准备从头到尾撸一遍,记录一下自己的心得。
前言:
ES5中声明变量只有两种方式:var
和function
,在ES6中新增了let
和const
方式。它们都是去定义一个变量,当然不同的方式含义也不同。
一、const
const
的中文含义是恒定的
,这里你可以理解为const
定义一个变量之后,它的值不可改变(这个说法不准确,后面会说到)。因为不可修改,所以声明时必须赋初始值。同时它只在声明的块级作用域之内有效,存在暂时性死区。下面是详细分析:
不可修改
const age = 23
age = 18 //Uncaught TypeError: Assignment to constant variable.
此时尝试修改age的值导致报错
必须给初始值
const age //Uncaught SyntaxError: Missing initializer in const declaration
未给初始值报错
不可重复声明
const age = 18
const age = 19 //Uncaught SyntaxError: Identifier 'age' has already been declared
重新声明已经声明过得变量报错
存在块级作用域
{
const age = 18
console.log(age) //18
}
console.log(age) //Uncaught ReferenceError: age is not defined
大括号为age所在的块级作用域,内部调用成功,外部报错,外部未发现变量age
无变量提升
if(true){
console.log(age) //ncaught ReferenceError: Cannot access 'age' before initialization
const age = 18
console.log(age) //18
}
未定义之前不可使用,即不存在变量提升。存在暂时性死区,即此时在age的块级作用域内,age为用const定义之前不可调用。
变量提升:变量可以在声明之前使用,值为
undefined
const person = {age:22};
console.log(person.age)//22
person.age = 33
console.log(person.age)//33
前面我们说到const
定义一个变量之后,它的值不可改变,但是这里我们定义一个对象,里面的数据却可以被修改。const
的含义是恒定的
,而这里恒定并不是指const
变量的值不变,而是变量的内存地址保持不变,当我们定义(数值、字符串、布尔
)简单类型的数据,此时内存地址保存的保存的便是这个值所以不可改变。而当定义一个(对象、数组
)时,保存的时一个指向该地址的指针,而指针指向的数据局结构时不被控制的,即可以修改。
const person = {age:22};
person = {age:22}
console.log(person.age)//test.html:15 Uncaught TypeError: Assignment to constant variable.
此时,person重新指向了另外一个对象(两个person对象不相等,因为指针不同),此时报错
二、var
es6之前, js用var来声明变量
无块级作用域
if(true)
{
var age = 88
}
console.log(age)//88
if是一个块级作用域,但外部可以调用age,说明var
不存在块级作用域
var
分为函数作用域(局部变量
)和全局作用域 (全局变量
)
全局变量
var age = 18
function show(){
console.log(age) //18
}
show()
console.log(age)//18
此时在函数外声明一个变量、函数内部和外部都可以调用,即函数外声明变量为全局变量
局部变量
function show(){
var age = 18
console.log(age)//18
}
show()
console.log(age)//Uncaught ReferenceError: age is not defined
此时变量声明在函数内部,即只可以在当前函数内调用,此时该变量为局部变量
有变量提升
console.log(age) //undefined
var age = 18
可以再变量声明前使用,但此时已声明还没赋值
,所以得到undefined
重复声明
var age = 18
console.log(age)//18
var age = 20
console.log(age)//20
可以重复声明变量
三、let
ES6新增的声明变量方式,与var类似
块级作用域
{
let age = 18
console.log(age) //18
}
console.log(age)//Uncaught ReferenceError: age is not defined
与const
一致,只在声明的块级作用域有效
变量提升
console.log(age)//Uncaught ReferenceError: Cannot access 'age' before initialization
let age = 18
无变量提升
,不可以在声明前使用
不可以重复声明
let age = 18
let age = 20//Uncaught SyntaxError: Identifier 'age' has already been declared
{
let age = 18
}
let age = 20
console.log(age)//20
let
不允许在相同作用域内,重复声明同一个变量。
暂时性死区
var age = 18
if(true){
console.log(age)//Uncaught ReferenceError: Cannot access 'age' before initialization
let age = 20
}
只要块级作用域内存在let(const
)命令,使用let(const
)命令声明变量之前,该变量都是不可用的。
总结:
1、const
(1)不可以重复声明
(2)声明前必须给初始值
(3)只在声明的块级作用域内有效,外部无效
(4)不存在变量提升,即不可再声明前使用。存在暂时性死区。
(5)声明的变量不可以修改(可以修改对象,数组的数据结构)
2、var
(1)可以重复声明
(2)不存在块级作用域,是有函数和全局作用域
(3)有变量提升,可以未声明前使用,值为undefined
3、let
(1)存在块级作用域,变量只在声明块级作用域有效
(2)无变量提升,不可以在声明前使用
(3)let不允许在相同作用域内,重复声明同一个变量。
(4)暂时性死区