javascript中的"调用上下文"和"执行上下文":我们在谈论同样的事情吗?

mar*_*rco 4 javascript

有时我读"调用上下文"有时候是"执行上下文".我想知道我们是否在讨论相同的概念.

我必须说在ECMAScript6规范中我没有找到任何对"调用上下文"的引用.

Sco*_*cus 14

这两个术语密切相关,但不是一回事.

简而言之,他们定义了范围背景.范围是关于代码运行的环境,上下文是关于导致某些代码被执行的实际对象.

"执行上下文"是指在某些代码运行时生效的"范围链".范围链是应该(以特定顺序)检查要解析为值的标识符(变量,常量和函数名称)的内存位置列表.由于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:
   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:
      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);
   }
}
Run Code Online (Sandbox Code Playgroud)

上面显示的三个执行上下文(范围)可以以各种方式输入.这些不同的方式产生了"调用环境".


"调用上下文"也可以更准确地称为"调用上下文对象",它指的是用于调用某些代码的对象.这可能看起来与"执行上下文"相同,但"调用上下文"指的是导致代码执行的 对象,并且执行代码在其自己的执行上下文(范围)内执行.

这两个术语之间最大的区别在于理解调用上下文导致this在执行上下文的持续时间内将关键字绑定到对象.thisJavaScript中的绑定是易失性的,this当您进入新的执行上下文时,绑定的对象会发生变化.对于所有意图和目的,this 调用某些代码的对象,还是this"调用上下文".

我写了另一个答案,详细介绍了如何确定this将绑定到什么,你可以在这里看到.

有关调用上下文的说明,请参阅以下代码段.它说明了一个 执行context(function foo),但是有两个 调用上下文(按钮和Global).

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);
Run Code Online (Sandbox Code Playgroud)
<button id="btnTest">Click Me</button>
Run Code Online (Sandbox Code Playgroud)

  • 这些报价是从哪里来的? (2认同)

Ber*_*rgi 5

执行上下文 ”是堆栈框架的正式术语(即,规范使用)。就像用语所说的那样,它为代码(当前)执行提供了上下文,该上下文主要由内部评估状态,当前评估的功能(代码)和活动变量范围组成。作为堆栈的一部分,它知道函数执行结束时返回的位置。

“调用上下文” 可能是指在其上调用方法的上下文对象,即objin obj.method()。它将成为该this函数中的值。规范没有在任何地方使用此术语,您会发现thisArgumentthisValuereceiver。在环境记录中被称为ThisBinding,它是每个执行上下文中包含的词汇环境(范围)的一部分。