一、JS运行三部曲
1、语法分析
2、预编译
3、解释执行
二、 预编译前奏
先记住两句话:
1、函数声明整体提升
test();
function test() {
console.log(a); --> 10
}
2、变量 声明提升
console.log(a); --> undefined
var a = 10;
console.log(a); --> 10
1、imply global 暗示全局变量:未经声明的任何变量,归window所有
a = 10; --> window.a = 10;
function test(){
var a = b = 123;--> window.b
}
test();
2、 一切声明的全局变量,归window
var b = 11; --> window.b = 11;
console.log(b) --> window.b
如下,声明的局部变量不归window所有。
function test() {
var b = 123;
}
test();
console.log(window.b); --> undefined
预编译发生在函数执行前一刻:
1、创建AO对象(Activation Object)
2、找形参和变量声明,将变量和形参的名拿来做AO的属性名,undefined
3、 实参和形参统一
4、找函数声明,函数名作为属性名,值赋予整个函数体。
function fn ( a ) {
console.log(a);
var a = 123;
console.log(a );
function a ( ) { }
console.log ( a );
var b = function (){ }
console.log ( b );
function d ( ){}
}
fn(1);
程序运行时,读到fn(1)即执行函数,在执行前的一刻进行预编译。
AO{
a : undefined --> 1 --> function a (){} --> 123,
b : undefined --> function(){},
d : function d ( ){}
}
全局预编译:
1、创建GO对象( Global Object , GO === window)
2、找函数声明,函数名作为属性名,值赋予整个函数体。 `
//全局预编译生成 GO{ b : 123}
function test(){
var a = b = 123;--> window.b
}
// 函数执行前预编译AO{ a : undefined}
test();
//GO{
gloabl : undefined --> 100,
fn : function fn(){...}
}
var global = 100;
function fn(){
console.log(gloabl);
}
//AO{ '找GO 的gloabl ' }
fn();
练习
1、
function test(){
console.log(b);//undefined
if(a){
var b = 100;
}
console.log(b);//undefined
c = 234;
console.log(c);//234
}
var a;
test();
a = 10;
console.log(c);//234
预编译过程:
GO{
a:undefined --> 10,
text:function test(){...}
c:234;
}
AO{
b: undefined;
}
2、
console.log(test); //function test(){...}
function test(test){
console.log(test);//function test(){ }
var test = 234;
console.log(test);//234
function test(test){
}
}
test(1);
var test = 123;
console.log(test);//123