JS运行的三部曲:
1.语法分析 通篇扫描一遍,看有没有语法错误,eg:用中文,少一半括号….
2.预编译 :发生在函数执行的前一刻。
预编译前奏:1.imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。
Eg:a =123;var a = b =123;
functiontest(){
var a = b = 234;
}
test();//
预编译四部曲:
1.创建AO对象(ActionObject执行期上下文)
2.找形参和变量声明,将变量和形参的名作为AO对象的属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,值赋予函数体
函数体里的预编译Eg1:function fn(a){
console.log(a);//functiona(){}
var a = 123;
console.log(a);//123
function a(){}//函数声明
console.log(a);//123
var b = function(){}//函数表达式
console.log(b);//functiond(){}
function d(){}//函数声明
}
fn(1);//
AO{
a:undefined,1,function a(){}
b:undefined
d:function d(){}
}
详细步骤:1.创建AO对象,AO{};2.找形参(a)和变量声明var a,var b,将形参和变量声明的名作为AO对象的属性名挂起来,出现两次的(a),挂一次,
AO{a:b:},值为undefined,AO{a:undefined,b:undefined};3.将实参值和形参统一,也就是将实参放进形参里面去,AO{a:1,b:undefined};4.在函数体里面找函数声明function a(){},function d(){},值赋予函数体AO{ a: functiona(){},b:undefined ,d:function d(){}}。AO对象创建完成
执行行数:第一条打印a,上哪找这个a,你写这个函数执行语句是给电脑看的,
你想拿东西的话,得去电脑定义好的那个箱子里拿东西,电脑定义好的箱子就是AO对象,而不是到你视觉效果上的a去拿,跟这个a没关系,视觉效果上的只是一个执行顺序,真正的是去AO{}里面拿东西,所以第一次拿的a是function a(){},然后第二句执行的是 var a= 123;这一句是不完全执行,因为在预编译的第二步就是找形参和变量声明,变量声明var a;已经被提升上去了,再声明就不用看了,所以只读a= 123;AO{ a: 123,b:undefined ,d:function d(){}};第二条再打印a,去AO对象里面去找a为123;function a(){}这一句在预编译的时候已经看了,被提升上去了,不用再看了;第三次打印a为123;var b;看了,所以现在执行b = function(){};AO{ a: 123,b: function(){},d:function (){}},打印b为function(){}
Eg2:function test(a,b){
document.write(a);
c = 0;
var c;
a = 3;
b = 2;
document.write(b);
function b(){};
function d(){};
document.write(b);
}
test(1);//123
详细步骤:1.创建AO对象AO{}; 2.找形参a,b和变量声明c,将变量和形参的名作为AO对象的属性名,值为undefined,AO{a:undefined,b:undefined,c:undefined}3.将实参值和形参统一,AO{a:1,b:undefined,c:undefined}
4.在函数体里面找函数声明function b(){};function d(){};,值赋予函数体
AO{a:1,b:function b(){};,c:undefined,d:function d(){}}
函数执行:document.write(a);//1
c = 0;//undefined-à0
var c;//已经被提升了
a = 3;//1à3
b = 2;// function b(){}à2
document.write(b);//2
function b(){};
function d(){};
document.write(b);//2:
Eg3:function test(){
console.log(a);// functiona(){}
console.log(b);//undefined
var b = 234;
console.log(b);//234
a = 123;
console.log(a);//123
function a(){}
var a;
b = 234;
var b = function(){}
console.log(a);//123
console.log(b);// function(){}
}
test(1);
2.一切声明的全局变量,全是window的属性。
Eg:var a = 123;====》window.a = 123;
test();
function test(){
console.log("a");
}
test();//a
console.log(a);
var a = 123;
console.log(a);// undefined 123
函数声明整体提升
变量 声明提升
console.log(a);
var a = 123;//等同于↓
var a;
console.log(a);
a = 123;//undefined
console.log(a);
function a(a){
var a = 234;
var a = function (){
}
a();
}
var a = 123;//
functiontest(){
var b = 234;
}
test();
console.log(window.b);//undefined
var a =123;
console.log(a);//相当于console.log(window.a);window就是全局
全局里的预编译(没有第三步):eg1:console.log(a);//undefined
var a = 123;
eg2:console.log(a);//function a(){}
var a = 123;
function a(){}
第一步生成的是GO对象(Global Object),
Eg3:var a= 123;
function a(){}
console.log(a);//123
GO{
undefined-->function a(){}-->123
} GO==window
Eg4:function test(){
var a = b = 123;
console.log(window.b);
}
test();//123
eg5:function test(){
var a = b = 123;
console.log(window.a);
}//undefined
未经声明的变量归Windows所有,先生成GO,在生成AO
Eg:console.log(test);
function test(test){
console.log(test);
var test = 234;
console.log(test);
function test(){}
}
test(1);
var test = 123;
详细过程:
GO{
test :undefined-->function test(test){console.log(test);vartest = 234;console.log(test);function test(){}}
}
AO{
test:undefined-->1-->functiontest(){}-->234
}
Eg: varglobal = 100;
function fn(){
console.log(global);
}
fn();//100
eg:var global = 100;
function fn(){
var global = 200;
console.log(global);
}
fn();//200
eg:global = 100;
function fn(){
console.log(global);//undefined
global = 200;
console.log(global);//200
var global = 300;
}
fn();
var global;
GO{
global:undefined-->100
}
AO{
global:undefined-->200
} eg:function test(){
console.log(b);//undefined
if(a){
varb = 100;
}
console.log(b);//undefined
c = 234;
console.log(c);//234
}
var a;
test();
/*AO{
b:undefined
} */
a = 10;
console.log(c);//234
/*GO{
a:undefined-->10
c:234
}*/