美文网首页
读懂预编译,不怕作用域面试题

读懂预编译,不怕作用域面试题

作者: 守护银河的河童 | 来源:发表于2018-12-04 15:12 被阅读0次

    我还记得之前很长一段时间被各种作用域面试题支配的恐惧(弱小无助.png)
    现在不怕啦,读懂作用域先理解预编译。
    来道简单题先:

    var a="aa";
    function test(){
      console.log(a);
     var a="bb";
       console.log(a);
    }
    test();
    console.log(a);
    

    答案:undefined bb aa

    几个概念解释下:

    预编译

    javascript是解释性语言,主要特点为解释一行执行一行。而在js运行时会进行三件事:
    1语法分析
    2.预编译
    3.解释执行
    语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误,预编译发生在代码执行的前一刻。所以,函数在执行时已经预编译过了。

    页面在创建之初就创建了GO(global object)对象,即window对象,所以全局变量也可以叫做window的属性。
    1、查找变量,作为GO属性,并赋值undefined。
    2、查找函数声明体,作为GO属性,并赋值函数体。

    预编译做了些什么事情

    1、查看语法错误,如果有错误就不执行接下来的代码。
    2、发现有调用函数时,创建AO(activation object)对象。
    3、查找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
    4、将实参值和形参统一
    5、在函数体里面找函数声明,值赋予函数体

    现在回到刚才的那道题:
    1、创建了GO对象

    GO{
       a:undefined, //查找变量,作为GO属性,并赋值undefined
       test:fun, //查找函数声明体,作为GO属性,并赋值函数体
    }
    

    2、执行js

    GO{
        a:"aa",  //变量a已存在,赋值‘aa’
        test:fun, 
    }
    

    3、读到函数调用,创建test函数的AO对象

    AO{
        a:undefined, //查找变量,作为AO属性,赋值undefined
    }
    

    4、执行test 函数

    console.log(a) //undefined
    

    此时有2个同名为a的变量,这里涉及到作用域链[[scope]]的概念,但是只要记住,自己有的用自己的,没有的再向父级寻找。
    此时,test函数AO对象内有a,且值为undefined,所以打印出来为undefined,

    AO{
        a:“bb”, //var a = 'bb'给a赋值
    }
    

    5、函数执行完毕

    console.log(a); // ‘bb’此时的a为全局变量a,父级不能访问子级的私有变量
    

    再来几道题,大家可以把答案写在下面:

    var fn
    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)
    console.log(fn)
    
    function test (a,b){
        console.log(a)
        c = 0;
        var c;
        a = 3;
        b =2;
        console.log(b);
        function b() {}
        function d() {}
        console.log(b)
    }
    test(1)
    
    console.log(test);
    function test(test){
        console.log(test);
        var test = 123
        console.log(test)
        function test (){}
    }
    test(1);
    var test = 123
    

    没有声明的变量赋值,默认为全局变量,不管在哪里都默认为全局变量。

    相关文章

      网友评论

          本文标题:读懂预编译,不怕作用域面试题

          本文链接:https://www.haomeiwen.com/subject/uvcmcqtx.html