欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈javascript引擎执行代码的步骤-(2019-2)

程序员文章站 2023-02-04 08:16:03
平时面试经常会遇到类似下面的这种题,而且千变万化,让人一个头两个。示例这道题算是稍微有点难度的了,这种题考查的是JavaScript引擎执行代码的步骤。 先上理论: (1)分析脚本的执行过程,也就是全局作用域下的代码。 ①创建全局对象GO(window) ②加载脚本代码 ③预编译:依此找到var开头 ......

平时面试经常会遇到类似下面的这种题,而且千变万化,让人一个头两个。示例这道题算是稍微有点难度的了,这种题考查的是javascript引擎执行代码的步骤。

b = 'cba';
function a(a, a){
    console.log(a);
    console.log(b);
    var b = 'abc';
    
    a();
    function a(){
        console.log(a);
        console.log(b); 
    }
}
a(5,10);

先上理论:

(1)分析脚本的执行过程,也就是全局作用域下的代码。

①创建全局对象go(window)

②加载脚本代码

③预编译:依此找到var开头的变量声明,把变量加入到全局对象中;找到function开头的函数声明,也放到全局对象中,如果有相同的变量名或函数名,替换之前的;非声明的语句不予理睬;

④解释执行,变量赋值,函数调用

(2)分析每个函数的执行过程

①创建每个函数对象ao(active object)

②预编译:创建作用域链;初始化arguments;初始化形参,绑定arguments和形参;找到变量声明加入到ao;找到函数声明加入到ao;

③解释执行

-----------------------------------------------------------------------------------------------------------------------------

具体分析上面的代码:

全局作用域下预编译阶段:
b = 'cba';//忽略,既不是变量声明,也不是函数声明
function a(a, a){//function开头的函数声明,go加入函数a,函数体忽略
    console.log(a);
    console.log(b);
    var b = 'abc';
    a();
    function a(){
        console.log(a); 
        console.log(b); 
    }
}
a(5,10);

全局作用域下解释执行:
b = 'cba';//go中加入变量b,且赋值为'cba'
function a(a, a){
    console.log(a);
    console.log(b);
    var b = 'abc';
    a();
    function a(){
        console.log(a); 
        console.log(b); 
    }
}
a(5,10);//执行函数a,然后生成a的ao

函数a的预编译阶段:
初始化arguments;
初始化形参,两个形参名都为a,后赋的值会替换先赋的值,a先赋值为5,后赋值为10,所以此时变量a为10;
console.log(a);//不是变量声明,忽略
console.log(b);//忽略
var b = 'abc';//是变量声明,将变量b加入到ao,值为undefined
a();//忽略
//函数声明,函数a与形参a同名,替换之前的a=10,此时a为function
function a(){
    console.log(a); 
    console.log(b); 
}

函数a解释执行阶段:
console.log(a);//输出function
console.log(b);//输出undefined
var b = 'abc';//变量b赋值'abc'
a();//执行,此处省略分析子函数a的预编译过程
function a(){
    console.log(a); //子函数a的ao中没有变量a,向父函数a中寻找,所以输出function
    console.log(b); //子函数a的ao中没有变量b,向父函数a中寻找,所有输出'abc'
}

有点乱哈,我写的可能也不是很清楚,不过这个真的很重要,我也是想通过这种方式能让自己加深印象,也希望有需要的人如果看到多少能提供一点帮助。