欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScrip变量提升的个人理解

程序员文章站 2022-03-03 19:55:13
在JavaScrip中,你可以在变量声明和函数声明之前调用它们,这很奇怪.举个栗子.函数调用可以放在声明之前,但是函数表达式必须放在声明之后.通常大佬会这么告诉小白,但是这其中是为什么呢,下面就让我们来仔细看看.首先,我们称这种现象为Hoisting变量提升,字面意思,变量声明和函数声明彷佛被优先提升至代码顶部.然而,JavaScript并不会改动我们的代码,这种"提升"实际上是,将声明优先放置到内存中,从而造成的现象.怎么理解呢,JavaScript是从上至下的进行编译执行的,这一点毋庸置疑.但是...

在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