简单谈谈个人对变量声明关键字var、let、const的理解。
初次写文,不够清晰严谨,还望体谅;错误之处还望指正。
变量声明的两个步骤:
- 定义(defined)
- 初始化(initialize)
var a // 定义变量a,并且初始化a为undefined
console.log(a) // output: undefined
一般来说,默认的变量声明还包括第三部:赋值(assignment),赋值的过程是将变量指向内存地址的过程
var a = 1 // 定义变量a,初始化为undefined,将a赋值为1,a指向1所在的内存地址
console.log(a) // output: 1
以下提到的变量声明均包含赋值的步骤。
Var、Let和Const三者的不同点:
- var声明的变量在全局范围内有效,let和const声明的变量只在当前作用域内有效。
“全局范围”是指当前js页面,不是全局变量“global”;“当前作用域”是指当前声明地址所在的范围,一般指中括号包含的区域,立即执行函数除外。
{
var a = 1
let b = 2 // 当前作用域为前后两个中括号之间
}
console.log(a) //output:1
console.log(b) //ReferenceError: b is not defined
- var声明的变量存在变量提升,变量的声明(定义和初始化,不包含赋值)会提升至最顶部,如下,变量x先赋值,再使用,最后声明,输出了正常结果,声明的位置没有影响。
x = 1
console.log(x) // expectedoutput:1
var x
let和cosnt没有变量提升,并且在当前作用域内有暂时性死区,当前作用域内声明之前调用会报错。
//(暂时性死区)
console.log(y) // ReferenceError: y is not defined
let y = 2
var a = 1
{
//(暂时性死区)
console.log(a) // ReferenceError: a is not defined
let a = 2
console.log(a) // expected output: 2
}
console.log(a) // expected output: 1
- var声明的变量可以再次声明和赋值。
var a = 1
console.log(a) // output: 1
var a = 2
console.log(a) // output: 2
let声明变量后不可再次声明,可以再次赋值。
let a = 1
console.log(a) // output: 1
a = 2
console.log(a) // output: 2
//不可重复声明
var a = 3 // SyntaxError: Identifier 'a' has already been declared
const声明的变量之后不可再次声明和赋值(但是变量的值可以改变,下方说明)。
const A = 1
//不可重复赋值
A = 2 // TypeError: Assignment to constant variable.
//不可重复声明
var A = 2 // SyntaxError: Identifier 'A' has already been declared
注:当const声明的变量为引用类型的时候,变量的值可以改变,引用类型和基本类型说明见附录。
const A = {
name:'Tom'
}
A.name = 'Lily'
console.log(A) // output: { name: 'Lily' }
附录:
基本(原始)数据类型(primitive data type):
Undefined、Null、Number、Boolean、String和Symbol(bigint在后续ES版本的标准中添加)
//例如:
123
0b10
"asd"
true
undefined
null
Symbol(1)
- 基本数据类型存储在栈内存(Stack)中
- 基本数据类型的比较是值的比较
var a = 1
var b = 1
console.log(a===b) // output:true
console.log(1===true) // output:false
- 基本数据类型的值是不可以改变的
var a = '111'
a.toUpperCase()
a[0] = '0'
console.log(a) // output: "111"
引用数据类型:
Object
这里的Object是引用数据类型对象的笼统称呼,包含Object、Array、Function以及用new关键字生成的Number、Boolean、String类型等
- 引用数据类型存在堆内存(Heap)中
- 引用数据类型的比较是内存地址的比较
var a = {name:"Tom"}
var b = {name:"Tom"}
//a和b在内存中的地址不一样
console.log(a===b) // output: false
- 引用数据类型的值可以改变
var a = {name:"Tom"}
a.name = "Lily"
//a所指向的内存地址没有改变
console.log(a) // output: {name:"Lily"}
到这里就很好理解了,const声明的变量的所指向的内存地址不可以改变,当const声明的变量指向基本数据类型时,变量的值不可以再改变,当const声明的变量指向引用数据类型时,变量的值可以改变。