javascript 引擎 预编译

预编译 - 脚本

  • 创建全局对象GO(window) global object(上下文)
  • 加载脚本文件
  • 预编译:

    • 找出所有的变量声明,按照变量名加入全局对象,如果已经存在,忽略
    • 找出所有的函数声明,按照函数名加入全局对象,如果已经存在同名变量或者函数,替换。
    • 非声明不予理睬
  • 解释执行
  1. 没有var的变量,都不是变量声明,全部都是window的全局变量,不参与预编译
  2. 即使在函数中,变量a没用var声明,也是全局变量(运行时,不是定义时)
  3. 脚本中,所有变量声明,在脚本的预编译阶段完成,所有变量的声明与实际书写位置无关
  4. 脚本中,所有函数声明,在脚本的预编译阶段完成,所有函数的声明与实际的书写位置无关
  5. 脚本中,如果变量与函数同名,那么,函数将覆盖变量
  6. 脚本中只有函数能覆盖变量,变量无法覆盖函数
  7. 脚本中,后面的函数声明会覆盖前面的函数声明,并且,忽略参数

预编译 - 函数调用

  • 创建活动对象AO (Active Object) (上下文)
  • 预编译:

    • scope chain
    • 初始化arguments
    • 初始化形参,将arguments中的值赋值给形参
    • 找出所有的变量声明,按照变量名加入AO,如果已经存在,忽略。
    • 找出所有的函数声明,按照函数名加入AO,如果已经存在同名变量或者函数,替换。
    • this初始化
  • 解释执行
  1. 函数中,所有变量声明,在脚本的预编译阶段完成,所有变量的声明与实际书写位置无关
  2. 函数中,所有函数声明,在脚本的预编译阶段完成,所有函数的声明与实际的书写位置无关
  3. 函数中,如果变量与函数同名,那么,函数将覆盖变量
  4. 函数中只有函数能覆盖变量,变量无法覆盖函数
  5. 函数中,后面的函数声明会覆盖前面的函数声明,并且,忽略参数
  6. 当函数预编译后,遇到需要访问的变量或者函数,优先考虑自己AO中定义的变量和函数(如果找不到,才会在其定义的上一层AO中寻找,直到到达GO)

练习

    console.log(scope);// undefined
    var scope = 'global'; 
    function t() {

        var scope = 't-local';

        function t2() {
            console.log(scope); // undefined
            var scope = 't2-local';
            console.log(scope); // t2-local
        }
        t2();
        console.log(scope); // t-local
    }
    t();
    console.log(scope); // global

javascript 引擎 预编译_第1张图片

    function test(x, x) {
        console.log(x); // function
        x = 5;
        console.log(arguments); // [12,5]
        function x() { }
    }
    test(12, 13);

在这里插入图片描述

    b = 'cba';
    function a(a, a) {
        console.log(a); // function
        console.log(b); // undefined
        var b = 'abc';

        a();
        function a() {
            console.log(a); // function
            console.log(b); // abc
        }
    }
    a(5, 10);

javascript 引擎 预编译_第2张图片

你可能感兴趣的:(javascript,前端)