预编译步骤
在script内代码块执行前
- 页面产生便创建了GO全局对象(Global Object)(也就是window对象);
- 第一个脚本文件加载;
- 脚本加载完毕后,分析语法是否合法;
- 开始预编译 查找变量声明,作为GO属性,值赋予undefined; 查找函数声明,作为GO属性,值赋予函数体;
在函数执行前
- 创建AO对象(Active Object)
- 查找函数形参及函数内变量声明,形参名及变量名作为AO对象的属性,值为undefined
- 实参形参相统一,实参值赋给形参
- 查找函数声明,函数名作为AO对象的属性,值为函数引用
题目
题目一
var bb = 1;
function aa(bb){
bb = 2
alert(bb)
}
aa(bb)
alert(bb)
// 答案
2 1
注释
在函数体内, bb并没有使用var来定义, 按理说这个bb在预处理的时候应该是window的属性. 但在这里, 函数声明的时候, 带了一个参数bb, 也就是相当于在函数体内声明了var bb. 所以, 函数里的bb就是函数活动对象的属性. 所以, 函数里的bb就是函数活动对象(OA)的属性. 所以函数执行时会输出2. 函数执行完后, 函数的活动对象被销毁, 也就是这个局部的这个bb被删除了, 执行流进入到window, 再输出bb, 值就是1了
var bb2 = 1;
function aa2(tt) {
bb2 = 2
console.log(bb2) //2
}
aa2(bb2)
console.log(bb2) //2
题目二
//原来的代码
var a = 1;
function test(){
// console.log(a) 位置A
class a {}
// console.log(a) 位置B
}
test()
//实际上提升后的
var a = 1;
funciotn test(){
console.log(a) 位置A // 在test() 作用域内找得到a, 是一个class但是存在TDZ暂时性死区, 访问错误
class a {}
console.log(a) 位置B // a已经声明出来了
}
//答案
报错
class a{}