关于Javascript中执行上下文的理解

JS解释器执行代码的过程:

  1. 定位到调用函数的code处;.
  2. 执行 function code前, 创建execution context.
  3. 进入创建阶段:
    • 初始化  Scope Chain.
    • 创建 variable object:
      • 创建 arguments object, check the context for parameters, initialize the name and value and create a reference copy.
      • 函数声明(Scan the context for function declarations):
        • For each function found, create a property in thevariable object that is the exact function name, which has a reference pointer to the function in memory.
        • 如果函数名已经存在,引用指针值将被重写(If the function name exists already, the reference pointer value will be overwritten.)
      • (变量声明)Scan the context for variable declarations:
        • For each variable declaration found, create a property in the variable object that is the variable name, and initialize the value as undefined.
        • 如果变量名已经存在,什么都不做,不影响已存在的变量声明。(If the variable name already exists in thevariable object, do nothing and continue scanning).
    • 确定context中 "this" 的值。
  4. Activation / Code Execution Stage:
    • AO是在进入函数的执行上下文时创建的,为上下文中的变量赋值。(Run / interpret the function code in the context and assign variable values as the code is executed line by line).

example:

function foo(i) {
    var a = 'hello';
    var b = function privateB() {

    };
    function c() {

    }
}

foo(22);

On calling foo(22), the creation stage looks as follows:

fooExecutionContext = {
    scopeChain: { ... },
    variableObject: {
        arguments: {
            0: 22,
            length: 1
        },
        i: 22,
        c: pointer to function c()
        a: undefined,
        b: undefined
    },
    this: { ... }
}

As you can see, the creation stage handles defining the names of the properties, not assigning a value to them, with the exception of formal arguments / parameters. Once the creation stage has finished, the flow of execution enters the function and theactivation / code execution stagelooks like this after the function has finished execution:

fooExecutionContext = {
    scopeChain: { ... },
    variableObject: {      //此处应该叫做AO
        arguments: {
            0: 22,
            length: 1
        },
        i: 22,
        c: pointer to function c()
        a: 'hello',
        b: pointer to function privateB()
    },
    this: { ... }
}

A Word On Hoisting

You can find many resources online defining the term hoisting in JavaScript, explaining that variable and function declarations are hoisted to the top of their function scope. However, none explain in detail why this happens, and armed with your new knowledge about how the interpreter creates the activation object, it is easy to see why. Take the following code example:

(function() {

    console.log(typeof foo); // function pointer
    console.log(typeof bar); // undefined

    var foo = 'hello',
        bar = function() {
            return 'world';
        };

    function foo() {
        return 'hello';
    } 
console.log(typeof foo);//string 这里可以测试出在AO对象中 foo的值==hello
console.log( foo());//报错,foo is not a function.  (变量声明是在函数声明和函数形参之后,所以执行后foo就是字符变量了,根据结果,个人理解)

}());

The questions we can now answer are:

  • Why can we access foo before we have declared it?
    • If we follow the creation stage, we know the variables have already been created before the activation / code execution stage. So as the function flow started executing, foo had already been defined in theactivation object.
  • Foo is declared twice, why is foo shown to be function and notundefined or string?
    • Even though foo is declared twice, we know from the creation stagethat functions are created on the activation object before variables, and if the property name already exists on the activation object, we simply bypass the decleration.
    • Therefore, a reference to function foo() is first created on theactivation object, and when we get interpreter gets to var foo, we already see the property name foo exists so the code does nothing and proceeds.
  • bar的值为什么是 undefined?
    • bar is actually a variable that has a function assignment, and we know the variables are created in the creation stage but they are initialized with the value of undefined.
这篇文章写得很赞,下班了,有空继续翻译。哈哈!

变量对象:如上

活动对象:感觉是进入执行上下文后,变量对象中的变量声明被赋值了、

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值