JavaScript是解释型语言,会先预编译,然后执行,在执行过程中顺序执行。
因此在JS中存在变量提升的现象
在函数中预编译执行步骤:
- 创建空AO对象,(Activity Object)执行期上下文
- 寻找函数的
形参
和变量声明
,将变量和形参作为AO对象的属性名,值为undefined - 将形参和实参相统一,将undefined更改为具体实参值。
- 寻找函数中的
函数声明
,将函数名作为AO属性名,值为函数体 - 预编译环节结束
- 执行,不断更新AO对象
- 执行完毕,AO对象销毁
全局对象GO也是一样
实例一
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(){}
}
- 创建空AO对象
AO{
// 空对象
}
- 寻找函数形参和变量声明
AO{
a: undefined,
b: undefined,
}
- 将形参和实参相统一
AO{
a: 1,
b: undefined
}
- 函数声明
AO{
a: function a(){},
b: undefined,
d: function d(){},
}
预编译环节结束,AO对象更新为
AO{
a: function a(){},
b: undefined,
d: function d(){},
}
函数开始顺序执行
function fn(a){
console.log(a); // function a(){}
var a = 123 // 对a赋值,AO对象改变
console.log(a) // 123
function a(){} // 预编译环节进行变量提升,执行时不看此行代码
console.log(a) // 123
var b = function(){} // 函数声明,对b重新赋值,AO对象改变
console.log(b) // function b(){}
function d(){} // 预编译环节变量提升,执行时不再看此行代码
}
实例二
function test(a,b){
console.log(a); // 1
c = 0; // AO更新
var c; // 预编译,不看
a = 3; // AO更新
b = 2; // AO更新
console.log(b); // 2
function b(){}; // 预编译,不看
function d(){}; // 预编译,不看
console.log(b); // 2
}
test(1); // 1 2 2
/**
AO1{}
AO2{
a: undefined,
b: undefined,
c: undefined,
}
AO3{
a: 1,
b: undefined,
c: undefined,
}
AO4{
a: 1,
b: function a(){},
c: undefined,
d: function c(){},
}
end;
**/
实例三
// 引入GO(全局对象)
console.log(test); // function test(test){,,,,,}
function test(test){
console.log(test); // function test(){}
var test = 234; // AO改变
console.log(test); // 234
function test(){} // 预编译,不看
}
test(1);
var test = 123;
执行结果:
// function test(test){,,,,,}
// function test(){}
// 234
解析过程:
/**
页面加载完成,生成GO对象
GO1{
test: undefined
}
GO2{
test: function(test){xxxxx}
}
执行test()钱生成AO对象
AO1{
test: undefined,
}
AO2{
test: 1
}
AO3{
test: function test(){}
}
预编译结束,开始执行
AO4{
test: 234
}
**/
实例四
function demo(){
console.log(b); // undefined
if(a){
var b = 100;
}
console.log(b); // undefined
c = 234; // 全局变量
console.log(c); // 234
}
var a;
demo();
a = 10;
console.logs(c); // 234
// undefined undefined 234 234
/*
GO1{
a: undefined
}
GO2{
a: undefined,
demo: function demo(){xxxxx},
}
执行demo函数前预编译,由于c未声明就使用,所以是全局变量
GO2{
a: undefined,
demo: function demo(){xxxxx},
c: undefined
}
a是undefined,if里不执行
输出undefined
GO4{
a : undefined,
demo : function demo(){}
c : 234;
}
//输出234
GO5{
a : 10,
demo : function demo(){}
c : 234;
}
//输出234
*/
网友评论