一、预编译
预编译阶段:就是作用域的创建阶段
作用域分为全局作用域和函数作用域
函数作用域创建阶段有一个 js的变量对象(AO对象)供js引擎自己去访问的
预编译做了哪些事情?
提升:名字相同时函数声明在变量声明前面
-
函数声明提升
-
var a 变量提升
-
值在执行到该行才进行赋值
-
创建ao对象
-
找形参和变量的声明 作为ao对象的属性名 值是undefined
-
实参和形参相统一
-
找函数声明 会覆盖变量的声明
function fn(a, c) {
console.log(a) //function a() { }
var a = 123
console.log(a) //123
console.log(c) //function c() { }
function a() { } //函数声明
if (false) {
var d = 678
}
console.log(d) //undefined
console.log(b) //undefined
var b = function () { } //函数的表达式
console.log(b) //function () { }
function c() { } //函数声明
console.log(c) //function c() { }
}
fn(1, 2)
//预编译阶段
AO:{ 2 3 4
a:undefined 1 function a() { }
c:undefined 2 function c() { }
d:undefined
b:undefined
}
//js逐行执行
js scope链
- 所有的function和var提前进行声明,
- 但是并不会对其进行赋值,
- 赋值则都是在该代码块进行执行时才会对其进行赋值
- 全局为一个scope,一个function为一个scope
- doit执行时才会创建新的Scope
所以为:
scope:b = 3
function doit(){
var b
console.log(b); // undefined
b = 3;
console.log(b); // 3
}
scope:a=1,b=2,function doit()
b=3
var a = 1;
var b = 2;
function doit(){
console.log(b); // undefined
var b = 3;
console.log(b); // 3
}
doit();
console.log(b); // 2
scope: a=1,b=2,function doit()
b = 3
var a = 1;
var b = 2;
function doit(){
console.log(a); // 1
// 重新声明了b
console.log(b); // undefined
var b = 3;
console.log(b); // 3
console.log(a); // 1
}
doit();
console.log(b); // 2
a向上检索 没有找到时就为undefined
var a = 1;
var b = 2;
function doit(){
console.log(a); // 1
console.log(b); // 2
b = 3;
console.log(b); // 3
console.log(a); // 1
}
doit();
console.log(b); // 2