浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的JavaScript解析器”开始工作。
JavaScript解析器工作步骤:
一、预解析。找一些全局标志:var、function参数。
□:如果遇到重名分以下两种情况。
→:如果是变量和函数重名,只保留函数;
→:如果是函数重名,根据上下文顺序,只保留最后一个。
二、逐行解读代码。
□:表达式可以修改预解析的值。
js解析器在执行第一步预解析的时候,会把这个代码捋一遍,从头到尾。只查找var、function和参数等内容。而且,找到这些内容后,所有的变量,在运行代码之前,都被赋予了一个值:未定义 undefined;所有的函数,在正式运行代码之前,都是整个函数块。
console.log(a);//执行:找到变量a,但是和两个函数a重名,保留函数a。两个函数,只保留后一个。打印出最后一个函数。
var a = 1;//声明变量,表达式会修改预解析的值。把a修改为1.
console.log(a);
console.log("--------------------");
function a() {
console.log(2);//什么都没打印出来
}
// a();//a is not a function
console.log("--------------------");
console.log(a);
var a = 3;
console.log(a);
console.log("--------------------");
function a() {
console.log(4);//因为没调用
}
// a();//a is not a function
console.log("--------------------");
console.log(a);
| 浏览器解析器 | 开辟内存 | ||
| 一、预解析 | 二、逐行执行语句 | 栈内存 | 堆内存 |
| → 先找到var关键字,两个var a,赋值为undefined | 打印a →发现a和函数同名,只保留最后一个同名的函数a | fun a(){4} | |
| → 再找function,两个fun a(),不做任何操作 | 表达式a → 表达式可以修改预解析的值 | a=1 | |
| → 变量和函数重名,保留函数a | 打印a → 输出1。修改后的值。 | ||
| → 两个函数重名,保留后一个 | 函数a →无打印输出 | ||
| → 再找参数,无。 | 表达式a → 还是上次定义的输出a | ||
| → 把找到的上述放在一个“待解释”区域,等待执行时进行求值。 | 表达式a → 重新赋值为3 | a=3 | |
| 输出3 | |||
| 此时若调用会出错,因为函数a在上面就被复写了 | |||
| 输出3 | |||
