JavaScript中的执行上下文

时间:2014-11-30 14:44:10

标签: javascript executioncontext

为JavaScript中的每个函数创建一个新的执行上下文。

运行以下代码时,内存中存在多少个执行上下文?请注意,不会调用函数Bar

function Foo () {

  function Bar() {}

}

Foo();

此外,何时创建执行上下文?在评估时或运行时?

4 个答案:

答案 0 :(得分:4)

创建函数时,它们在运行时编译。调用它时会调用该函数。

让我解释一下:

您可以拥有任意数量的功能上下文,每个功能调用都会创建一个新的上下文。

//Global Context
var helloWorld = "hello world!";
function foo(){//execution context
  function bar(){//execution context
   console.log('bar');
  }
}
foo();

因此,在上面的代码函数中调用foo,并为函数foo创建新的上下文,bar的执行上下文仅在您调用它之后创建,但它在运行时已经编译。

当浏览器第一次加载脚本时,它默认进入全局执行上下文。如果在全局范围内调用函数,程序的顺序流将进入被调用的函数,创建新的执行上下文并将该上下文推送到执行堆栈的顶部。

现在让我们详细了解执行上下文:

因此,每次调用函数时,都会创建一个新的执行上下文。对执行上下文的每次调用都有两个阶段:

<强> 1。创作阶段:

当函数被调用但在它执行之前的任何代码之前是:创建范围链,创建变量,函数和参数,并确定&#34;这个&#34;的值。

<强> 2。激活阶段:

分配值,引用函数并执行代码。


Now, let's have a bit more knowledge of execution context

function foo (a, b, c) {
    function z(){alert(‘Z!’);}
    var d = 3;
}
foo(‘foo’,’bar’);

foo()调用中的ExecutionContext:步骤1:创建参数

ExecutionContext: {
    arguments: {
        0: ‘foo’, 1: ‘bar’,
        length: 2, callee: function() //Points to foo function
    }
}

步骤3a:变量实例化,参数

ExecutionContext: {
    arguments: {
        0: ‘foo’, 1: ‘bar’,
        length: 2, callee: function() //Points to foo function
    },
    a: ‘foo’, b: ‘bar’, c: undefined
}

步骤3b:变量实例化,函数

ExecutionContext: {
    arguments: {
        0: ‘foo’, 1: ‘bar’,
        length: 2, callee: function() //Points to foo function 
    },
    a: ‘foo’, b: ‘bar’, c: undefined,
    z: function() //Created z() function
}

步骤3c:变量实例化,变量

ExecutionContext: {
    arguments: {
        0: ‘foo’, 1: ‘bar’,
        length: 2, callee: function() //Points to foo function
    },
    a: ‘foo’, b: ‘bar’, c: undefined,
    z: function(), //Created z() function,
    d: undefined
}

第4步:设置此值

ExecutionContext: {
    arguments: {
        0: ‘foo’, 1: ‘bar’,
        length: 2,  callee: function() //Points to foo function
    },
    a: ‘foo’, b: ‘bar’, c: undefined,
    z: function(), //Created z() function,
    d: undefined,
    this: window
}

在创建ExecutionContext之后,该函数从第一行开始运行其代码,直到找到返回或函数结束。每次此代码尝试访问变量时,都会从ExecutionContext对象中读取它。

答案 1 :(得分:4)

函数的运行时调用是导致创建执行上下文的原因。因此,在您的示例中,只有一个函数调用,因此只涉及一个执行上下文。

函数的静态(编译时)排列很重要,因为它确定了范围和执行上下文的最终内容。然而,对于创建上下文而言重要的函数的实际调用。 (一些较旧的语言使用术语&#34;激活记录&#34;,尽管这可能更适用于基于堆栈的分配。)

你可以用the spec的有时翻天的语言阅读细节,尽管很难弄清楚森林的树木。规范是根据转移的控制来编写的。函数调用是一种非常常见的方式,但是事件处理程序的调用,或者在浏览器最初加载时调用完整的<script>块也是如此。

答案 2 :(得分:3)

致电Foo();

  • 由于调用了单个function
  • ,因此创建了单个执行上下文
  • 在此过程中还会创建指向函数Bar的指针。

此外,还有一个默认环境,您的代码首次执行,称为全局上下文

答案 3 :(得分:1)

我最好的猜测是,它可能取决于您运行代码的环境。

虽然检查V8并不是很难,但是根本没有为没有执行的函数创建执行上下文。

Executed function Non-executed function