JS运行三部曲

1、语法分析
2、预编译
3、解释执行(逐行执行)

预编译前奏

1、任何变量未经声明就赋值,这个变量就为全局对象(window)所拥有
2、全局上声明的任何变量,即使声明了也归window 所有;window就是全局的域

函数预编译

1、创建 AO 对象(Activation Object 俗称执行期上下文)
2、找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
3、将实参值和形参统一
4、找函数声明,会覆盖变量的声明

题目一

global = 100

function fn(){
var a = b = 1
console.log(global)
global = 200
console.log(global)
var global = 300
console.log(global)
}

fu()
console.log(a)
console.log(b)

解题一

// 预编译前奏
GO = {
global: 100,
b: 1
}
// 预编译阶段
// 1、创建AO对象
AO = {}
// 2、找形参和变量声明
AO = {
a: undefined,
global: undefined
}
// 3、将实参值和形参统一
AO = {
a: undefined,
global: undefined
}
// 4、找函数声明,会覆盖变量的声明
AO = {
a: undefined,
global: undefined
}

// 解释执行阶段
global = 100

function fn(){
console.log(a) // undefined
var a = b = 1
console.log(a) // 1
console.log(global) // undefined
global = 200
console.log(global) // 200
var global = 300
console.log(global) // 300
}

fn()
console.log(a) // Error
console.log(b) // 1
console.log(global) // 100

题目二

function fn(a, c){
console.log(a)
var a = 'a'
console.log(a)
console.log(c)
function a() {}
if(false){
var b = 'b'
}
console.log(b)
console.log(d)
var d = function (){}
console.log(d)
function c(){}
console.log(c)
}
fn(1, 2)

解题二

// 预编译阶段
// 1、创建AO对象
AO = {}
// 2、找形参和变量声明
AO = {
a: undefined,
b: undefined,
c: undefined,
d: undefined
}
// 3、将实参值和形参统一
AO = {
a: 1,
b: undefined,
c: 2,
d: undefined
}
// 4、找函数声明,会覆盖变量的声明
AO = {
a: function a(){},
b: undefined,
c: function c(){},
d: undefined
}

// 解释执行阶段
function fn(a, c){
console.log(a) // function a(){}
var a = 'a'
console.log(a) // a
console.log(c) // function c(){}
function a() {}
if(false){
var b = 'b'
}
console.log(b) // undefined
console.log(d) // undefined
var d = function (){}
console.log(d) // function (){}
function c(){}
console.log(c) // function c(){}
}

注意点:var b = function(){} 为函数表达式

总结

1、预编译前奏

  1. 创建GO对象
  2. 两个规则

2、函数编译四部曲

  1. 创建 AO 对象(Activation Object 俗称执行期上下文)
  2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
  3. 将实参值和形参统一
  4. 找函数声明,会覆盖变量的声明