(javascript 函数 预编译问题详解)
js 三部曲
- 语法分析 -----> 预编译 ------> 解释执行
预编译前奏
function test(){
console.log('a');
}
test(); //可以执行
test();
function test(){
console.log('a');
} // 这样也可以执行
就是因为预编译的存在
var a = 123;
console.log('a');
答案:123
console.log('a');
var a = 123;
答案:undefined
console.log('a');
这样会报错
总结 :
函数声明整体提升: 函数不管被写到哪里 ,都会被提到逻辑的最前面,所以不管在那里调用,本质上都是在后面调用。
变量 声明提升 把 var a 提升到最前面
var a = 123; 这是 变量声明在赋值
变量 声明提升 是把 var a = 123; 拆分 var a; a=123; 然后把 var a 提升到最前面。
- imply global 暗示全局变量 ,即任何变量未经声明就赋值了,那么此变量就为全局所有,全局就是(window)。
- 一切声明的全局变量,全是window 的属性 eg: var a =123; —> window.a = 123;
- window 就是全局的域
预编译发生在函数执行的前一刻
**函数预编译的四部曲**
1. 创建一个AO 对象 activation Object (执行期上下文),作用是理解的作用域,函数产生的执行空间库。
2. 找形参和变量声明,把变量名和形参名,作为AO的属性名,值为undefined。
3. 将实参和形参相统一(把实参的值传到形参里面)
4. 在函数体里面找函数声明,值赋予函数体。
就近原则 先看 自己 的 AO ,自己的AO里面没有再去全局找GO;
全局预编译三部曲
1. 生成一个 GO对象 Gloab Object (window就是Go)
2. 找形参和变量声明,将变量名和形参名作为GO 的属性名,值为undefined
3. 在函数体找函数声明,值赋予函数体。
GO === Window Go 和 window 是一个东西
没有声明就赋值了,就是归全局所有,就是在GO中预编译
先执行GO 先执行 AO 的问题 ?
要想执行全局,先生成GO,在函数执行的前一刻生成函数的AO
在几层嵌套关系,近的优先,从近的到远的,有 AO 就看 AO,AO 没有才看 GO