当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JavaScrip变量提升的个人理解

JavaScrip变量提升的个人理解

2020年07月17日  | 移动技术网IT编程  | 我要评论

在JavaScrip中,你可以在变量声明和函数声明之前调用它们,这很奇怪.
举个栗子.函数调用可以放在声明之前,但是函数表达式必须放在声明之后.通常大佬会这么告诉小白,但是这其中是为什么呢,下面就让我们来仔细看看.

首先,我们称这种现象为Hoisting变量提升,字面意思,变量声明和函数声明彷佛被优先提升至代码顶部.
然而,JavaScript并不会改动我们的代码,这种"提升"实际上是,将声明优先放置到内存中,从而造成的现象.

怎么理解呢
第一,JavaScript是单线程的,也就是说它只会一段一段的从上而下的执行代码
第二,JavaScript运行代码分为两个阶段: 编译+执行
第三,编译阶段变量提升.将变量放置到内存环境之中,等待执行时调用.
综上,不难理解"提升"的意思.其实代码没有位置变化,只是JavaScript优先加载了这些变量而已,看上去它提升到了顶部.

问题解决了吗,显然没有.我们继续
JavaScript对于var,const,let,function等关键字封装的都有提升,不过"提升"完全度不一样而已.
怎么说呢,就像这样

alert(a);	//undefined
alert(b);	//function b(){};
alert(c);	报错c is not defined,并不在继续执行;需将这一行注释,下方alert才可以继续弹出1
var a=1;
alert(a);	//1
function b(){};

发生了什么呢.
一开始编译,我们检索到了var和function关键字,进行"提升".var声明提升,并赋值undefined(注意赋值undefined,这是电脑做的事情,不是人做的事情,不是我们的本意);function声明提升,同时进行了具体定义.
然后执行,我们进行alert弹出a是undefined,弹出b的函数.
至于弹alert( c),为了和alert(a);对比.c不存在,所以报错,而a存在,所以弹出undefined值.
然后遇到了a=1;代码给a赋具体值了,所以再次弹alert(a),弹出了具体值1,这才是我们的本意.
注意当执行到var a=1;这行代码时,实际上这里,没有重复声明var,而是只有赋值行为.
这里需要注意的是,JavaScript是不会重复声明的,由于编译阶段的提升已经提升了,所以执行阶段不再声明.同样的还有function也不再声明.

知识点
var提升:声明
function提升:声明+定义
不会重复声明,
不允许存在重名,所以再次定义(赋值)会进行覆盖

对了,还有一件事.当变量和函数重名时,怎么办呢.
很简单,覆盖.
谁覆盖谁呢.这里涉及到提升时的优先级问题.
网路上大神的说法是,函数提升优先级高于变量提升,但是不会被变量声明覆盖,但是会被变量赋值覆盖.
何解?以下为个人看法,尝一下这个好吃的栗子

	alert(a);	//	function a(){alert(1);}
    var a = 1;
    alert(a);	//	1
    function a() {alert(1);}
    var a = function () {alert(2);}
    alert(a);	//	function () {alert(2);}

可以这么理解,一下代码并不严谨,仅供理解

	function a() {alert(1);}
	//	var a;		这里需要理解var a;已经被忽略了,所以并没有覆盖
	alert(a);	//	function a(){alert(1);}
    a = 1;
    alert(a);	//	1
    a = function () {alert(2);}	//	这里的函数表达式,其实是通过变量来访问的,也具有变量提升的效果,同样忽略了var a;
    alert(a);	//	function () {alert(2);}

这里需要理解,其实就是变量提升var a;为什么会被忽略掉.
之前已经说过了,JavaScript不会重复声明,重复的声明都会被忽略.

复杂地讲,函数提升时,其实也是将函数名作为变量名存放在内存中的.函数名变量名,只是重名,那么JavaScript在编译阶段进行提升时,都认为是同一种东西.所以后面的变量声明是重复声明了.被忽略了.这也就是大佬所说的,函数提升不会被变量声明覆盖.但是在执行阶段的变量赋值,已经不在是同一种东西,JavaScript不会进行忽略,所以被覆盖掉了.

简单地讲,如果重名的函数声明和变量声明,不是同一种东西,JavaScript分的清的话,那么为什么会存在覆盖呢?如果是两种东西,覆盖优先级这些通通不存在.所以必然是同一种东西,必然会被忽略.

综上理解,我们在来解释一开始的问题,函数调用可以在声明之前,函数表达式必须在声明之后.

第一,变量提升
第二,函数表达式通过变量访问,也具备变量提升的效果
第三,变量提升:声明
第四,函数提升,声明+定义
第五,不存在重复声明(忽略),定义(赋值)进行覆盖
第六,函数提升优先于变量提升,即使表面看起来情况与之相反,但是请注意,忽略重复声明
第七,提升的范围,只在它所在的作用域

理解浅显,如有错误,请大佬指出
另外,如果各位姥爷们觉得阔以的话,记得点赞收藏哦,爱你们哦(๑◕ܫ←๑)b

本文地址:https://blog.csdn.net/MojaveGhost1057/article/details/107279694

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网