问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

js变量提升与函数提升到底怎么提升

发布网友 发布时间:2022-04-07 05:36

我来回答

2个回答

懂视网 时间:2022-04-07 09:58

变量提升

JavaScript的变量提升有两种,用var声明的变量以及用function声明的变量。

用var声明的变量

我们先来看下面这段代码,a的值是多少

代码1

console.log(a);

var a;

按照以往编程语言的思路来看,代码自上而下运行,按这种思路,会报错,因为执行到第2行时,变量a还没有定义,所以会报错a is not defined

然而事实上答案是undefined

好,抱着疑惑,我们看下面的代码

var a;
console.log(a);

我们发现,这两段代码是一样的,那么又有一个新的问题,是不是有没有var a都无所谓,它的答案始终是undefined,才造成了以为变量会提升的错觉,于是我写了代码3

代码3

console.log(a);

好,它终于报错了,所以这证明了javaScript代码并不是自上而下执行的,至少从表面看上面是这样的。

于是我们再看代码4

代码4

console.log(a);
var a = 2;

因为变量提升嘛,所以答案是2,然而事实上,它依然是undefined,why?

这时候我们有请编译器这位负责语法分析及代码生成等脏活累活的大佬。

编译器在看到var a = 2;,它会将其看做两个声明,var a;和a = 2,第一个声明在编译阶段进行,第二个声明会被原地等待执行阶段。

也就是说上面代码,会变成下面的这段代码

var a;
console.log(a);
a = 2;

所以最终会是undefined

好,我在啰嗦一下,看这段代码5

代码5

a = 2;
var a;
console.log(a);

我想大家应该已经知道这段代码执行时的真正顺序及其答案了,没错,答案是2,但我想说的是把第2行给注释掉,答案依然是2,但这个和变量提升没啥关系了,是严格模式与非严格模式的锅,在非严格模式下允许开发者可以不使用声明变量的关键字,但在严格模式下是不可以的,它会报错的。

用function声明的变量

与var一样,function声明的变量依然会提升。

log(5);

function log(mes){
 console.log(mes)
}

按照之前的变量提升的理解,这段代码的真正顺序是这样的,

function log(mes){
 console.log(mes)
}

log(5);

很好,很正确,那么再看下一段代码

log(5);

var log = function(mes){
 console.log(mes)
}

它报错了,log is not a function,从这里我们可以看出,这种函数表达式是不会被提升的,只有函数声明才会被提升,试着在最前面新增一行代码console.log(log),会先输出undefined。

所以这里的真正顺序是

var log;
log(); //这时候只是声明了log这个变量,并不是函数,却用函数的方法调用它,所以会报错,说这不是一个函数。
log = function(mes){
 console.log(mes)
}

在function里用var声明变量

我们虽然知道,var声明的变量会提升,但并不知道会提升到哪个程度。

在此之前来看一段代码

var a = 4;

function foo(){
 var a = 5;
 console.log(a);

}
foo();

console.log(a)

答案是5,4,先输出5,再输出4。

用var声明的变量是有函数作用域的,所以foo里的a和foo外面的a没有任何关系,这种情况正是我想要的。

再改下代码

function foo(){
 a = 5
 console.log(a);
 var a;
}
foo();

console.log(a)

答案是5,a is not defined

第4行代码输出5,第9行报错。

这种情况就是变量提升只会提升到变量所在的 作用域的顶部,不会提升到父级作用域。

因此可以得出一个结论:变量提升只会将变量提升到自己所在的作用域的顶部

函数优先

既然用var和function的变量都有提升的功能,那如果同一个变量用这两种都声明会怎样,好吧,看标题就知道了,函数优先。

具体看下代码

foo();

var foo;

function foo(){
 console.log(1)
}

foo = function(){
 console.log(2)
}

答案是1

这段代码其实这样子的

function foo(){
 console.log(1)
}

foo();// 1

foo = function(){
 console.log(2)
}

仔细一看,var foo;没了,没错,它被引擎忽略了,认为重复声明所以把它抛弃了。

好,既然var声明的变量比不了函数声明,那就用函数声明,多次声明同个变量。

foo()
function foo(){
 console.log(1);
}
foo()
function foo(){
 console.log(2);
}
foo()
function foo(){
 console.log(3);
}

foo()

foo声明了三次,调用了四次,每次调用的结果都是3,所以最后的函数声明会覆盖之前的函数声明

但是var还想挣扎一下,觉得还是有必要证明自己的存在感的。

foo()
function foo(){
 console.log(1);
}
var foo;
foo()
foo = function(){
 console.log(2);
}
foo()
function foo(){
 console.log(3);
}

foo()

仔细看,中间那部分代码改了,依次输出3,3,2,2

虽然var foo被忽略了,但下面的函数还是有用的,这段代码可以看成是这样的

function foo(){
 console.log(3);
}

foo();//3
foo();//3
foo = function(){
 console.log(2);
}
foo();//2
foo();//2

在普通块内部声明函数

之前是在作用域声明函数,现在来块里面声明函数

function foo(){

 console.log(b); // undefined
 b(); //TypeError: b is not a function

 var a = true;

 if(a){
 function b(){
 console.log(2)
 }
 //下面这段代码和上面的结果一样
 // var b = function(){
 // console.log(2)
 // }
 }
 //b() --> 这里会被执行

}

foo()

从上面看上去,b是undefined,证明这个变量还是有的,只不过它并不是一个函数,这情况和用函数表达式差不多。

总结

1、提升分为函数声明提升和变量声明提升

2、声明变量用var,声明函数用function

3、变量提升会将变量提升到自己所在作用域的顶部

4、函数表达式不存在提升的机制

5、函数声明和变量声明同时声明同一个标识符时,函数声明优先

6、多个函数声明同一个标识符时,最后一个声明覆盖先前的声明

推荐教程:js教程

热心网友 时间:2022-04-07 07:06

举个例子吧

document.body.onclick=function(){ alert(c); }
var c=123;
这里虽然变量是在后面定义的,但点击的时候依然能取到。这就是变量提升,js定义变量时,都会在内存中存储改变量,直至退出变量所在的执行环境。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 呼伦贝尔油玉不绝电子商务有限公司怎么样? 如何避免wps卡顿? 属鼠的男人找对象是属什么,属鼠的人和什么属相合 96年鼠的姻缘在哪年 属相相合年份运势提升 2024属鼠找对象属什么最佳 黑客攻击网站能报案吗 黑客攻击报案有用吗 怎样把照片发到不是自己QQ好友的邮箱里 水煮丸子的做法和步骤视频 串并联电流规律 15. 在假设检验中,当接受原假设时,可以认为原假设绝对正确。( )判断题 清水煮素丸子的做法 关于串、并联电路中电流、电压规律的解释 统计学假设检验怎么判断拒绝还是接受 串联和并联中电流的规律 假设检验中,p值小于检验水平,应该拒绝原假设还是还是接受,为什么 在eviews中怎样判断是否接受原假设 统计学的P值与α=0.05之间关系的具体含义是什么?为什么P>0.05就要接受原假设? 水煮丸子怎么做 探究串并联电路中的电流规律教案 在假设检验中,所计算的概率正好等于小概率a 应当 拒绝还是接受原假设,请详述理由 探究串并联电路中电流的规律 假设检验中,为什么接受原假设不代表原假设成立 探究串并联电路电流的特点的实验做完后应注意哪些问题 配对样本t检验中,t值-2.105 相伴概率0.073 置信度95% 结果是不是接受原假设? 另t值有什么用? 水煮丸子的做法,水煮丸子怎么做好吃,水煮丸子的家常 助计量经济学高手!!P值与接受或拒绝原假设之间的关系是?? 下雨天的姐弟俩的故事,动漫 推荐一本可以学习photoshop的书 学习photoshop比较好的书。 学习ps比较好的书有哪些?? 章子怡夸奖马嘉祺好的可怕,娱乐圈还有哪些像他这样有演技的小鲜肉? 现在的小鲜肉演员有谁有演技还肯努力? 娱乐圈的小鲜肉中谁的演技最令你惊喜? 除了张一山以外,还有哪些演技好的小鲜肉? 娱乐圈的小鲜肉中,谁才算真正的有演技? 小鲜肉贡献演技,实力派更显实力,一众演员在《八佰》中飙戏,你看了吗? 现在年轻的小鲜肉还有那个演技不错? 王俊凯被赞敬业,娱乐圈的小鲜肉有哪些是实力派? 现在小鲜肉很多,有那些小鲜肉的演技是过关的? 哪些小鲜肉演技比较过关? 《送你一朵小红花》发预告片,易烊千玺演技在线,还有哪些有演技的小鲜肉? 现在的小鲜肉你觉着谁的演技最好? 你觉得哪个小鲜肉是当之无愧的演技派? 盛一伦演戏哭不出来被李成儒痛批,娱乐圈里还有哪些演技有待提高的小鲜肉? 当红流量小鲜肉有哪些有演技的瞬间? 当下最火的四大小鲜肉,哪个最有演技