导言:ES6
引入了const
let
从而引入了块作用域的概念,使JS的内容更为丰富,那么var
const
let
这三者的区别是什么呢?
区别
const
let
具有块状作用域的作用,var
没有var
具有变量提升的特点,const
let
不具有- 在声明语句之前访问
const
let
所声明的变量会报错,这也是第二点的补充
块状作用域
在es6
之前只有函数作用域和全局作用域,除开这两个作用域,在{}
内部用var
声明的变量是在外部是可以正常访问的,es6
之后出现了块状作用域,即引入了let
const
,使得{}
也有了作用域的功能,即在{}
内定义const
let
,外部无法访问let
const
所定义的变量,如下代码:
// var
function testVar(){
if(1) {
var b = 3;
}
console.log(b);
}
testVar(); // 3
// let
function testLet(){
if(1) {
let b = 3;
}
console.log(b);
}
testLet(); // error: Uncaught ReferenceError: b is not defined
变量提升
在作用域中,用var
所声明变量,是可以提前访问的,只不过该值为undefined
,而const
let
则会报错;
// var
function testVar(){
console.log(b); // undefined
var b = 3;
}
testVar();
// let
function testLet(){
console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 3;
}
testLet();
简单的说,其实就是对于var
的声明而言,会做类似以下的操作:
// 模拟var的变量提升
function testVar(){
var b = undefined;
console.log(b);
b = 3;
}
testVar();
所以它正常输出了
那都是对变量进行声明的操作,为什么两者有如此区别呢?(const
let
算是同一者,因为它们之间只是一个声明变量,一个声明常量的区别而已)
JS代码的执行过程
造成两者如此差别的原因,就得从一段JS代码的执行过程开始说起!
// 一段JS代码
test();
console.log(testVar);
function test(){
console.log('test function');
}
var testVar = 'testVar';
上述一段代码,在JavaScript引擎
是怎么执行的呢?
其实JavaScript引擎
执行一段代码的过程分两个阶段
- 编译阶段
- 执行阶段
编译阶段
在编译阶段过程中,代码会分为两部分
- 执行上下文
- 可执行代码
在执行上下文中,分为两个部分一个部分为变量环境
,另外一个部分为词法环境
变量环境里面放的就是变量声明以及函数声明,其实这就是变量提升的实际操作,引擎为test函数以及testVar开辟出内存,内存里面的初始化,如testVar
为undefined
而函数声明则直接是函数体,这也是为什么test函数以及testVar
在前面能正常执行;
// 模拟编译完之后的代码的执行顺序,模拟!!实际并不是这样
function test(){
console.log('test function');
}
var testVar = undefined;
test();
console.log(testVar);
testVar = 'testVar';
执行阶段
而执行阶段就要简单得多:
- test函数入栈执行
- testVar赋值为
'testVar'
那么来看看const
let
的块状作用域是怎么编译的?
// 一段含有let,const的JS代码
var a = 1;
var b = 2;
let c = 3;
{
var d = 4;
let e = 5;
var f = 6;
}
执行过程:
之前编译阶段的词法环境
终于用上场了
在这里,var
声明的变量,不管是在{}
外面还是里面,都会放在变量环境里面做变量提升
的操作,而let
以及const
声明的变量,则会进入到词法环境中类似一个栈
结构一样,被维护起来
具体流程如下:
a,b,d,f
进入变量环境做变量提升
{}
外的d
先入词法环境的栈
{}
内的e
后入词法环境的栈
至此,完成编译阶段
那执行阶段是如何访问这些变量的呢
先从词法环境的栈顶
开始访问,一直到栈底
,最终返回到变量环境进行访问
如: a = 1
赋值语句先从词法环境的栈顶
开始访问,一直到栈底
,最终返回到变量环境进行访问,最终给a
赋值为1
,而c = 3
则直接从词法环境访问到了,就不进入变量环境了
当然,词法环境中的变量是被{}
限定的,每一次入栈
对应的是一个作用域,如c
则是全局的作用域
,所以只能在全局上下文中被访问到,而e
则是在{}
内的作用域,只能在{}
中被访问到,{}
中的代码执行完后,e
的词法作用域出栈
,变量被销毁,就如同函数的出入栈
一致
总结
const
let
与var
的区别主要是:
const
let
具有块状作用域的作用,var
没有var
具有变量提升的特点,const
let
不具有- 在编译阶段,
var
放入到变量环境中,而const
var
放入到词法环境中,并维护一个类似栈
的词法作用域栈
本文内容为自己对var
const
let
三者区别的总结与归纳,如有问题,请指正!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!