作用域分为两种,一种是词法作用域,一种是动态作用域。事实上 JavaScrtip 并不具有动态作用域。它只有词法作用域。

 

如果非要从 JavaScript 中找到动态作用域,那么动态作用域是 this 的表亲。this 是 JavaScript 一个重要的机制

 

function foo() {
  console.log(a); // 2
}
function bar() {
  var a = 3;
  foo();
}
var a = 2;
bar();

 

运行这段代码,输出 2。为什么,因为词法作用域让 foo() 中的 a 通过 RHS 引用到了全局作用域中的 a,因此输出 2。

 

动态作用域并不关心函数和作用域是如何声明以及在何处声明的。只关心它们从何处调用。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套。如果 JavaScript 具有动态作用域,理论上将会输出 3 。

 

因为当 foo 无法找到 a 的变量引用时,会顺着调用栈在调用 foo 的地方查找 a,而不是在嵌套的词法作用域链中向上查找

 

JavaScript 并不具有动态作用域。它只有词法作用域,简单明了。但是 this 机制某种程度上很像动态作用域