javascript 预解析
所谓预解析,既是函数执行的前一刻,js需要做的事情,函数的预解析分四步:
一、创建AO对象
二、寻找函数中的形参及变量声明,并把形参和变量的名作为AO对象的属性名,值为undefined
三、实参、形参相统一
四、寻找函数中的函数声明,并把函数名作为AO对象的属性名,函数整体赋值给该属性名,如果函数名与变量名重复,则把函数体直接赋值给变量
注意,以上为函数的预解析,如果是全局下执行某段js代码,它的预解析步骤与函数预解析步骤基本一致,差别有两点:
一、全局作用域下,创建的不是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(){}
}
fn(1);
函数执行前 执行预解析
第一步:创建AO对象
1 | AO {} |
第二步:寻找函数中的形参及变量声明,并把形参和变量的名作为AO对象的属性名,值为undefined
1 2 3 4 | AO { a:undefined, b: undefined } |
注:形参和变量重名时,只写一个即可,即:写一个a即可
第三步:实参、形参相统一
AO {
a:1,
b: undefined
}
第四步:寻找函数中的函数声明,并把函数名作为AO对象的属性名,函数整体赋值给该属性名,如果函数名与变量名重复,则把函数体直接赋值给变量
1 2 3 4 5 | AO{ a:function(){}, b:undefined, d:function(){} } |
至此,js的预解析执行完毕,开始逐行执行代码
第一行:console.log(a); js到AO对象里找 a 所以 打印 function(){}
第二行:var a = 123; 因为预解析时 var a已被提升,所以这一行只是给a赋值,此刻AO对象里的a变为123;
AO{
a:123,
b:undefined,
d:function(){}
}
第三行:console.log(a); js到AO对象里找a 所以打印 123;
第四行:function a(){} 预解析时已提升,所以 忽略
第五行:console.log(a); js到AO对象里找a 所以打印 123;
第六行:var b = function(){} 因为预解析时 var b已被提升,所以这一行只是给b赋值,此刻AO对象里的b变为function(){};
AO{
a:123,
b:function(){},
d:function(){}
}
第七行:console.log(b); js到AO对象里找b 所以打印 function(){};
第八行:function d(){} 预解析时已提升,所以忽略
函数执行完毕!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步