发布时间:2023-04-06 11:30
js高级第一章–变量提升,函数提升
在js中,最基本的声明方式有三种,即:var,let,const,为什么在已经有var关键字的前提下,js后续更新了let和const关键字,那就说明var本身是有缺点的或者说不够直观严谨,本文将介绍var关键字引发的问题----提升。
直接上代码:
console.log(a);
var a=3;
按理说,按照js单线程的逻辑,这里输出的应该是报错,即
a is not defined
因为我们想的是在没有定义a之前打印输出了a变量,理应报这个我们还未定义a的错误,可事实真的如此吗,我们来看实际输出的结果:
undefined
结果竟然输出的是undefined,也就是js认为现在a已经定义过了,但是没赋值。
这是怎么回事?我们明明把定义和赋值写在了第二行。
这,就是本文介绍的,提升。
console.log(a);
var a=6;
简单说就是在js代码执行前引擎会先进行预编译,预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。
也就是说刚才的代码,js的执行过程其实是这样的:
var a;
console.log(a)
a=6;
js的var关键字把变量声明,提升到了最顶端,然后才去执行剩下的编译代码,这也是最基本的变量提升案例了。
注意:变量提升只提升声明,不提升赋值
我们来看这样一个例子
function chifan(){
console.log('我要吃米饭')
}
chifan()
function chifan(){
console.log('我要吃面')
}
chifan()
可以看到,定义了chifan函数,分别输出两个字符串,按照我们对js单线程的逻辑理解,执行的代码结果应该是:
‘我要吃米饭’
‘我要吃面’
可实际上呢:
'我要吃面'
'我要吃面'
这就是所谓的js的函数提升,我们使用的是函数声明的方式,所以js会有类似于变量提升的函数提升,与变量提升不同,函数提升不仅仅提升函数声明,而是提升函数整体,具体过程即:
var chifan=function (){
console.log('我要吃米饭')
}
var chifan=function (){
console.log('我要吃面')
}
chifan()
chifan()
我们可以看到,函数提升不仅仅把声明做了提升,同时还把赋值跟着声明一起提升到了最前面
再来看下面这个例子
var game=function (){
console.log('玩英雄联盟')
}
game()
var game=function (){
console.log('玩CSGO')
}
game()
这里并没有用函数声明的方式,而用的是函数表达式的方式,所以并不存在函数整体提升,仅仅也只是声明提升,具体执行过程如下:
var game
var game
game=function (){
console.log('玩英雄联盟')
}
game()
game=function (){
console.log('玩CSGO')
}
game()
所以 输出的结果当然是:
'玩英雄联盟'
'玩CSGO'
看下面这段代码:
console.log(drink)
function drink(){
console.log('酒')
}
var drink='饮料'
这里我们可以看到drink即是函数声明的函数,又在最后赋值了一次,这样去执行时,如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性,具体编译过程如下:
var drink=function drink(){
console.log('酒')
};
console.log(drink);
var drink='饮料';
所以 输出的结果当然是:
[function:drink]
因为我们并没有加(),所以打印的就是函数本身而不是函数方法。
本篇介绍了js中的提升,如有错误,欢迎探讨指正。
另外,使用let和const关键字不存在提升,也是现在大多数人不再用var的原因。