Skip to content

Latest commit

 

History

History
29 lines (22 loc) · 1.41 KB

File metadata and controls

29 lines (22 loc) · 1.41 KB

附录A:动态作用域(Appendix A: Dynamic Scope)

之前提到的使用 evalwith 能创建所谓的 动态作用域,介绍它们只是为了和 词法作用域 形成对比,出于性能和代码可维护角度考虑,千万别用它们来写代码!

动态作用域 和后面要讲的 this 机制有异曲同工之妙。所谓的 动态,即指在 代码运行时,区别于 代码书写时静态

function foo () {
  console.log(a); // 2
}

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

var a = 2;

bar();

👆在 foo 中关于变量 aRHS 是属于 词法作用域 的范畴,即在 foo 书写时就确定了其作用域是全局作用域;同理于 baz,其书写时的作用域是 函数作用域(bar)。因此 foo() 输出 2baz 输出 3

如果是 动态作用域,当 foo 执行时,其输出的结果应该是 3,因为理论上它的作用域链是基于函数的 调用栈(call-stack) 而非链上嵌套的 词法作用域

清晰的讲,JS并没有实际上所谓的 动态作用域,而 this 只是某种类似 动态作用域 的机制而已。

关键的区别:词法作用域是建立在写代码时,动态作用域是建立在代码运行时。前者关心函数是在哪儿 声明(declared) 的,后者关心函数是在哪儿 调用(called) 的。