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

javascript 怎么解决变量提升

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

我来回答

3个回答

懂视网 时间: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

“变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确。
因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升(Hoisting)。
JS 存在变量提升,这个的设计其实是低劣的,或者是语言实现时的一个副作用。它允许变量不声明就可以访问,或声明在后使用在前。
新手对于此则很迷惑,甚至许多使用JS多年老手也比较迷惑。但在 ES6 加入 let/const 后,变量Hoisting 就不存在了。

热心网友 时间:2022-04-07 08:24

在javascript 中,变量同名·冲突了,可以修改变量名解决冲突问题。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 呼伦贝尔油玉不绝电子商务有限公司怎么样? 如何避免wps卡顿? 属鼠的男人找对象是属什么,属鼠的人和什么属相合 96年鼠的姻缘在哪年 属相相合年份运势提升 2024属鼠找对象属什么最佳 黑客攻击网站能报案吗 黑客攻击报案有用吗 汽车国五和国六的有什么不一样的 怎么看电压表测哪个? 怎么判断电压表是测哪两端的电压? 怎么看电压表是测量哪一个用电器 复杂电路中怎样看电压表、电流表侧谁 初三物理如何判断电压表是测量哪一部分的电压.希望附图详细讲解, 同上 怎么看电压表测的电压? 初中物理如何看电压表 初中物理,怎样看电压表测哪里电压? 如何辨别电压表测得是电路的电压还是个别电阻的电压? 电压表怎么看它测的是电源的电压还是灯泡的电压? 我是做物业的,最近我们小区出现了乱扔垃圾在电梯内,应该怎样写温馨提示 禁止楼道小便的提示语 委婉一点?跪求 维护校园环境卫生的提示语 禁止楼道堆放杂物的温馨提示怎么写? javascript 变量提升有什么用 解答行程问题时注意什么? 怎样学好数学行程问题 行程问题三道 小学行程问题如何解答? 写出一般的解题思路,我对这类题总是很头疼,谢谢! 上海浦东金桥禹州国际三期属于哪个派出所管辖 金湘路225号 禹洲金桥国际三期2号楼219号 是什么工厂在招人,今天打电话教我去面试,还不知道什么工厂呢 从汤巷馨村二期到金港路333号保安亭走进来在禹洲金桥国际三期1号楼1133怎么坐公交和地铁地铁 上海市浦东新区新金桥路禹州国际三期二号楼238室是在哪个镇? 禹州金桥国际怎么样?好不好?值不值得买? 农业银行借记卡有利息吗 谢谢 禹洲金桥国际的小区详情 上海禹洲金桥国际二手房 怎么样 禹州金桥国际商住房买下来自住好吗 上海火车站到上海浦东新区金港路333号禹州金桥国际大厦 借记卡有利息吗 ???卡里会增加钱?? 从南翔怎么才能到浦东新区金桥金豫路 禹洲金桥国际 谢谢! 请问上海浦东新区禹州金桥国际一期有宽带么,为什么我问了联通电信移动有线通都没有啊 浦东新区金港路333号禹洲金桥国际一期 是属于哪个居住地街道?办社保的时候要用到 中国银行的借记卡有利息吗?大概是多少? 农行借记卡没给利息的吗 爱吼K歌怎么用不了了……是不是倒闭了????有类似爱吼那样的软件介绍吗?? 为什么进爱吼k歌的时候显示网络不给力 手机K歌用什么牌子的话筒效果好 K歌软件,mac系统上用的,多谢推荐