这是《你不晓得的JavaScript》中的一个典型问题,个人感觉挺重要的,所以对其总结演绎。
1.在书中的鸡指什么?蛋指什么?
鸡指赋值,蛋指申明。
在JS中引擎会在解释JavaScript之前对其进行编译。编译这一步会先找到所有的申明,换句话说所有变量或者函数的申明会在任何代码执行之前先被解决
引擎:负责JavaScript程序的编译及执行过程
编译器:负责语法分析及代码生成
对于var a = 2
在JavaScript中会被分成两部:
1. var a;(编译)2. a=2;(执行)
编译器执行过程:
1.遇到 var a ,编译器会询问作用域是否曾经有一个该名称的变量存在于同一个作用域的汇合中。如果是,编译器会疏忽该申明,持续进行编译;否则它会要求作用域在以后作用域的汇合中申明一个新的变量,并命名为 a 。
2.接下来编译器会为引擎生成运行时所需的代码,这些代码被用来解决 a = 2 这个赋值操作。引擎运行时会首先询问作用域,在以后的作用域汇合中是否存在一个叫作 a 的变量。如果是,引擎就会应用这个变量;如果否,引擎会持续查找该变量。
这时来看书中的问题:
a=2;var a;console.log(a);//2console.log("--------------");console.log(a2);//undefinedvar a2=2;
在JS理论执行中会被转成
var a;a=2;console.log(a)var a2;console.log(a2);a2=2;
这样再看为什么一个输入2一个输入undefined就高深莫测了。
书中还有一个留神点:函数申明的优先级比变量高
foo();//1var foo;function foo(){ console.log(1);}foo=function(){ console.log(2);}
总结:
1.在JS执行前会先编译,找出所有变量,函数的申明。
2.如果反复申明变量且没赋初值会疏忽申明(可看上编译器执行过程),如果赋初值会笼罩后面该变量的值。