一、js预编译
    js是单线程,但并不是分析一行执行一行。代码执行前,会先进行预编译(会检查语法错误),然后再执行
    预编译会有:
    变量提升函数提升函数声明优先级高于变量声明优先级。同一个执行上下文中,如果存在多个同名函数声明,后者会替换前面的

    二、执行栈
    执行栈用于保存执行上下文,栈底压着全局执行期上下文,函数每次调用都创建一个新的执行期上下文,放进栈顶,函数执行完后,该执行期上下文会被移出执行栈,控制权交给栈顶的执行期上下文。

    1. var scope = "global scope";
    2. function checkscope(){
    3. var scope = "local scope";
    4. function f(){
    5. return scope;
    6. }
    7. return f();
    8. }
    9. checkscope();
    10. //执行栈情况:
    11. ECStack.push(<checkscope> functionContext);
    12. ECStack.push(<f> functionContext);
    13. ECStack.pop();
    14. ECStack.pop();
    15. var scope = "global scope";
    16. function checkscope(){
    17. var scope = "local scope";
    18. function f(){
    19. return scope;
    20. }
    21. return f;
    22. }
    23. checkscope()();
    24. //执行栈情况:
    25. ECStack.push(<checkscope> functionContext);
    26. ECStack.pop();
    27. ECStack.push(<f> functionContext);
    28. ECStack.pop();
    29. //这两段代码的执行栈运行情况不一样

    三、变量对象与活动对象
    函数上下文中,用活动对象(Activation Object)来表示变量对象。
    变量对象是规范上或者js引擎上实现的,并不能在js环境中直接访问。进入函数执行期上下文时,变量对象被激活,成为活动对象,此时活动对象上的属性与方法才可以访问到。
    进入函数执行上下文时,会创造arguments对象,并将传入的实参作为arguments对象的数组元素(arguments时类数组,一种对象,有length属性)
    预编译过程:
    1、找形参、变量、函数声明给oa添加属性
    此时形参赋值和变量声明为undefined
    2、寻找实参参数给形参赋值
    3、寻找函数体声明,给AO添加函数方法。
    4、执行代码