var,let,const
在ES6之前,JavaScript定义变量都是使用var,而在ES6之后,出现了两个新的定义变量的关键字let和const
var
-
可以重复声明变量,但是后声明的变量会覆盖前面声明的同名变量
-
声明的变量为全局变量,并且会将该变量添加为全局属性
-
不存在块级作用域
-
存在变量提升
说这个需要先了JavaScript引擎是怎么工作的,它会先将整个脚本扫描一遍,将所有var定义的变量都先提升到开头,例如function test(){ var a = 1 ... } //会变成 var a function test(){ a = 1 ... }
-
不存在暂时性死区
-
var声明的变量会挂载在window上
let和const
-
存在块级作用域
- 这一特性解决了ES5的什么问题?
- 内层变量可能会覆盖外层变量
- 用来计数的循环变量泄露为全局变量
- 这一特性解决了ES5的什么问题?
-
不存在变量提升,即变量只能在声明之后才能使用,否则会报错
-
不能重复声明变量
-
存在暂时性死区
只要进入当前作用域(有了块级作用域),所要使用的变量就已经存在了,但是不能获取,只有等到声明变量的那行代码出现,才可以获取和使用该变量
- ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量,就会报错
- let和const声明的变量不会挂载到window上,它形成了一个块级作用域
- 那么在全局作用域中,let和const声明的变量哪去了?
在es5中,全局变量会直接挂载到全局对象window的属性上, 但是在es6中,全局变量从全局对象中脱离出来,但是为了兼容性,使用var,function声明的全局变量依然可以在window对象上看到,但是let和const声明的全局变量在window对象上看不到,在script中形成一个块级作用域,在全局下可以如下面例子这么访问
let a = 10 const b = 20 console.log(window.a) console.log(window.b) console.log(a) console.log(b) //输出 undefined undefined 10 20
- 那么在全局作用域中,let和const声明的变量哪去了?
let
let创建的变量是可以更改指针指向,可以重新赋值
const
const声明的变量是不允许改变指针的指向
用来定义常量,定义变量后需要立即初始化,并且之后不能修改
这里说的不能修改,指的是不能修改变量指向的那个内存地址所保存的数据
这里情况分为两种讨论:
对于基本数据类型,变量所指向的内存地址保存着的就是它们原本的值,所以不可以修改
但是对于引用类型,如Object,变量指向的内存地址所保留的数据也只是个指针,这个指针是固定的,该指针指向的是在堆中开辟出来的一小块用于存储Object对象里的属性的内存空间(而一般像基本数据类型都是直接存储在栈中),至于这块内存空间存储的属性,是可以改变的,是不受控制的。