这是《你不知道的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);//2

console.log("--------------");

console.log(a2);//undefined
var a2=2;

在JS实际执行中会被转成

var a;
a=2;
console.log(a)

var a2;
console.log(a2);
a2=2;

这样再看为什么一个输出2一个输出undefined就一目了然了。

书中还有一个注意点:函数声明的优先级比变量高

foo();//1
var foo;
function foo(){
    console.log(1);
}
foo=function(){
    console.log(2);
}

总结:
1.在JS执行前会先编译,找出所有变量,函数的声明。
2.如果重复声明变量且没赋初值会忽略声明(可看上编译器执行过程),如果赋初值会覆盖前面该变量的值。


符道胜
1 声望1 粉丝

Gitee地址:[链接]