【问题标题】:"Invocation context" and "execution context" in javascript: are we talking of the same thing?javascript中的“调用上下文”和“执行上下文”:我们说的是同一件事吗?
【发布时间】:2016-12-29 19:10:46
【问题描述】:

有时我会阅读“调用上下文”有时会阅读“执行上下文”。我想知道我们是否在谈论同一个概念。

我必须说,在 ECMAScript6 规范中,我没有找到对“调用上下文”的任何引用。

【问题讨论】:

  • 你在哪里读到这个?在非技术性或草率的文档中,它可能指的是同一件事
  • @Bergi OP 并没有说他读到这两个术语是相同的,他只是说他听说过这两个术语。由于它们是相关的,因此很自然地想知道它们是否是同一事物的两个不同术语。
  • @ScottMarcus 它们如何/是否相关并不是很明显。我只是说这两个术语可能指的是同一个概念(这使得答案为“也许。”),以确保我们需要知道这些术语是在什么上下文中使用的。
  • "..我们需要知道在哪个 context 中使用了这些术语。"好吧,现在你只是厚脸皮。 ;)
  • 我没有在同一个地方阅读这两个术语

标签: javascript


【解决方案1】:

这两个术语密切相关,但不是相同的东西。

简而言之,他们定义了 scopecontext 范围是关于代码运行的环境(有点像房间 - - 它是关于代码的位置),上下文是关于导致某些代码被执行的实际对象(比如谁负责把你放在那个房间里)。

“执行上下文”指的是 "scope chain" 在某些代码运行时生效。作用域链是一个列表 应该检查的内存位置(按特定顺序) 要解析为的标识符(变量、常量和函数名称) 一个值。由于 JavaScript 是在单线程中执行的 环境下,一次只能执行一项任务。目前的 执行代码(及其相关范围)定义执行 上下文。

一个简单的例子可以这样展示:

// This area is in the Global execution context (scope) because the code is 
// not wrapped in a function or any other kind of code block.
var x = "Global";

// "Global" is the result because the JavaScript engine will always look
// in the current scope for a declaration for the identifier in question.
// It will find a declaration for "x" right here in the Global scope, so
// that's the value it will use.
console.log(x); 

var y = "Also Global";

function parent(){
   // This area is in the "parent" execution context (scope)
   var x = "parent";

   // "parent" is the result (not "Global") because when this function is
   // executing, its scope is the most accessible. The JavaScript engine
   // looks here first to find out what "x" is. This is known as variable 
   // "hiding" because the x in the parent scope hides the x in the Global scope.
   console.log(x); 

   function child() {
      // This area is in the "child" execution context (scope)
      var x = "child";

      // "child" is the result (not "Global" or "parent") because when this 
      // function is executing, its scope is the most accessible. The 
      // JavaScript engine looks here first to find out what "x" is. This
      // x now hides the x in parent, which is hiding the x in Global.
      console.log(x); 

      // "Also Global" is the result here. First the current execution
      // context (scope) is checked for a "y" variable. There isn't one,
      // so the next scope in the scope chain (function parent) is checked.
      // There is no "y" declared there either. So, again, the next highest
      // scope in the chain (Global) is checked and that is where "y" is
      // found, so the value of that "y" is used.
      console.log(y);

      // Here, we will get "undefined". All the scopes in the chain will
      // be checked and if we go all the way up to Global and still don't
      // find a declaration for "z", there is no other scope to look in.
      console.log(z);
   }
   child();
}

parent();

上面显示的三个执行上下文(范围)可以通过多种方式进入。这些不同的方式产生了“调用上下文”。


“调用上下文”也可以更准确地称为 “调用上下文对象”指的是 object 用于调用一些代码。这似乎与 “执行上下文”,但“调用上下文”是指 object 导致代码执行并且正在执行的代码正在这样做 在它自己的执行上下文(范围)内。

这两个术语的最大区别在于理解调用上下文导致关键字this 在执行上下文期间绑定到对象。 this 绑定在 JavaScript 中是易变的,this 绑定的对象在您进入新的执行上下文时会发生变化。出于所有意图和目的,this 调用某些代码的对象,或者this 是“调用上下文”。

我已经写了另一个答案,其中更详细地介绍了如何确定this 将绑定到什么,您可以看到 here

有关调用上下文的说明,请参见以下 sn-p。它说明了一个 执行上下文 (function foo),但两个 调用上下文(按钮和全局)。

function foo() {
  // When this function is "invoked" via the button click
  // the invocation context is the button and the console will
  // log this as: [object HTMLButtonElement]
  
  // But, when the function is invoked from a direct call to foo
  // from the Global execution context, this will be bound
  // to the window object. So, in that case we'll get: [object Window]
  console.log("The 'this' object (invocation context object) is: " + this);
}

// Call foo from the Global execution context.
foo();

var btn = document.getElementById("btnTest");

// When the button is clicked, execute foo
btn.addEventListener("click", foo);
<button id="btnTest">Click Me</button>

【讨论】:

  • 这些引用来自哪里?
  • @Oriol 他们来自我(除非另有链接)。
【解决方案2】:

execution context”是堆栈帧的官方术语(即规范使用的)。正如措辞所说,它为代码的(当前)执行提供了上下文,它基本上由内部评估状态、当前评估的函数(代码)和活动变量范围组成。作为堆栈的一部分,它知道函数执行结束时返回到哪里。

“调用上下文”可能是指调用方法的上下文对象,即obj.method()中的obj。它将成为该函数中this 的值。该规范在任何地方都没有使用这个术语,你会发现thisArgumentthisValuereceiver。它在 environment record 中称为 ThisBinding,它是每个执行上下文中包含的 lexical environment(范围)的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 2015-01-28
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多