一、题目形容

以下代码输入程序

var a = 1;console.log(a);function fn(a, c){    console.log(a);    var a = 123;    console.log(a);    console.log(c);        function a(){};    if(false) {      var d = 999;    }    console.log(d);    console.log(b);        var b = function(){};    console.log(b);        function c(){};    console.log(c) } var c = function (){  console.log("I at C function"); } console.log(c); fn(1, 2);

二、剖析

  1. 页面产生便创立了GO全局对象(Global Object)
  2. 第一个脚本文件加载
  3. 脚本加载结束后,剖析语法是否非法.
  4. 开始预编译,查找变量申明,作为GO属性,值赋予undefined; 查找函数申明,作为GO属性,值赋予函数体;

    //形象形容GO/window = { a: undefined, c: undefined, fun: function(a, c) {     ... }}

    解释执行代码(直到执行调用函数fn(1, 2)语句)后,每个属性都赋了值

    //形象形容GO/window = { a: 1, c: function (){     console.log("I at C function"); } fn: function(a) {     ... }}

    所以在fn执行前打印出了

    1function c() {}

    执行fn前也产生了一次函数预编译,创立了AO流动对象(Active Object)

    // 首先查找形参和变量申明,并赋值 undefinedAO = { a: undefined, c: undefined, d: undefined, b: undefined}// 把实参赋值给形参AO = { a: 1, c: 2, d: undefined, b: undefined}// 接下来查找函数申明,会笼罩变量申明AO = { a: function a() {}, c: function c() {}, d: undefined, b: undefined}

    而后开始解释执行:

  5. 第一个console.log(a),毫无疑问会打印出咱们下面剖析的值 function a() {}
  6. 第二个console.log(a),因为后面对变量a赋值了123,所以打印出123
  7. 第三个console.log(c),打印出function c() {}
  8. 第四个console.log(d),因为条件语句的条件是false,所以不会进行赋值,打印出undefined
  9. 第五个console.log(b),打印出undefined
  10. 第六个console.log(b),后面一句为变量b赋值了一个函数,所以打印出function() {}
  11. 第七个console.log(c),打印出function c() {}

综上所述,咱们就能够晓得

// 全局环境内首先打印出了1function c() {}// 执行 fn 函数后打印出function a(){}123function c(){}undefinedundefinedfunction (){}function c(){}

三、总结

剖析预编译时,只有依照上面的步骤进行剖析,咱们就可能找出正确的答案了

  1. 创立AO对象
  2. 先找形参和变量申明,再找函数申明
  3. 形参和实参相对立
  4. 查找函数申明,会笼罩变量申明