在一个阳光明媚的早晨,Y同窗拿着手里的早餐——鸡蛋不由想起一个问题,先有鸡仍是先有蛋呢?因而和C同窗讨论起来这个问题,双方各执一词。这时候W同窗过来讲:不如以最近学的JavaScript代码中变量的声明和赋值问题一决胜负吧!markdown
Y方观点:先有鸡(赋值)才有蛋(声明) Vs C方观点:先有蛋(声明)才有鸡(赋值)app
Y同窗随手敲了下面的代码:函数
a = 2;
var a;
console.log(a);
复制代码
猜猜console.log会输出什么呢?ui
Y同窗:这里输出的是undefined
,JavaScript代码在执行上是按照由上到下一行一行去执行的,天然而然var a;
从新把a赋值了,所以会输出undefined
。url
C同窗:我认为会输出2,由于var会进行变量提高,由于在代码执行前是要预编译的。spa
Y同窗:我不听我不听,拿代码来讲服我。3d
C同窗:那你看这段代码会输出什么呢?code
console.log(a);
var a = 2;
复制代码
Y同窗:你先说吧,我思考下(内心偷偷想,既然你说了var会变量提高,那必定输出2了,哈哈哈)orm
这时候有同窗看到了,直接说,在严格模式下,变量a没有先进行声明,所以会抛出ReferenceRrror异常。cdn
C同窗:我认为会输出undefined
。(暗自窃喜,我赢定了...)
Y同窗:你刚刚不是说var能够变量提高,怎么如今反悔了(噘嘴)?
W同窗:那我们就一块儿来看看是怎么回事吧!
同窗们拿着瓜子搬好板凳。
小黑板:首先咱们得知道JavaScript事实上是一门编译语言,它的编译原理和传统的编译语言很是类似。在传统的编译语言的流程中,程序中的一段源代码在执行前会经历三个步骤:
(具体解释下回分解,本次直接对题进行分析)——(瓜子不够了)
在咱们看到var a = 2;
这句代码中,可能会认为这是一个声明,但JavaScript实际上会解析为两句代码var a; a = 2;
第一句是在编译阶段进行的,第二句会原地等待执行阶段的到来。Y同窗写的代码实质上是这样的:
var a;
a = 2;
console.log(a);
复制代码
一样C同窗的第二段代码实质上是这样的:
var a;
console.log(a);
a = 2;
复制代码
在这里就发生了变量提高,对于变量而言,那就是先有声明才有赋值。(提高的定义:不管做用域中的声明出如今什么地方,都将在代码自己被执行前首先进行处理,能够将这个过程形象地想象成全部的声明(变量和函数)都会被“移动”到各自做用域的最顶端,这个过程被称为提高。)
C同窗:那就是先有蛋才有鸡了,哈哈哈。
W同窗:敲了敲黑板,平时咱们在写代码的过程当中,要注意的是:
只有声明自己才会被提高,赋值以及其余逻辑会留在原地,若是提高改变了代码执行的顺序,会形成严重的破坏;
并且函数声明也会被提高,重点是函数会首先被提高,而后才是变量。
在声明时注意避免重复声明,特别是普通的var声明和函数声明混合在一块儿的时候,不然你们就是上班写bug,下班改bug。
本次battle C同窗得到胜利,奖励蜜雪冰城一杯(撒花~)。