美文网首页JavaScript
词法作用域 VS 动态作用域

词法作用域 VS 动态作用域

作者: 康斌 | 来源:发表于2016-10-12 08:54 被阅读1989次
Javascript的词法作用域

作用域是个语言无关的概念,你要接触过Lisp或者Scheme等语言,应该对这个概念会非常熟悉。我在这篇文章会介绍词法作用域和动态作用域的基本知识,让你刚好对这个概念了解,此外,我们还会讨论下JavaScript的词法作用域。

首先你得明白程序设计中作用域这个概念:通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域

词法作用域,也叫静态作用域,它的作用域是指在词法分析阶段就确定了,不会改变。动态作用域是在运行时根据程序的流程信息来动态确定的,而不是在写代码时进行静态确定的。

我们以下面这段Javascript代码来说明词法作用域和动态作用域,但是你要明白,阐述的概念是与Javascript无关的。

var a = 2;

function foo() {
  console.log(a); // 会输出2还是3?
}

function bar() {
  var a = 3;
  foo();
}

bar();

如果是词法作用域,它会让 foo() 函数引用到全局作用域中的 a,因此会输出 2。我们说过,词法作用域是写代码的时候就静态确定下来的。Javascript中的作用域就是词法作用域(事实上大部分语言都是基于词法作用域的),所以这段代码在浏览器中运行的结果是输出 2

Javascript作用域链

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

为什么会这样?因为当 foo() 无法找到 a 的变量引用时,会顺着调用栈在调用 foo() 的地方查找 a ,而不是在嵌套的词法作用域链中向上查找。由于 foo() 是在 bar() 中调用的,引擎会检查 bar() 的作用域,并在其中找到值为 3 的变量 a

你可能会觉得很奇怪,但这其实是因为你可能只写过基于词法作用域的代码(或者至少以词法作用域为基础进行了深入的思考),因此对动态作用域感到陌生。如果你只用基于动态作用域的语言写过代码,就会觉得这是很自然的,而词法作用域看上去才怪怪的。

需要明确的是,Javascript并不具有动态作用域,它只有词法作用域,简单明了。但是,它的 eval()withthis机制某种程度上很像动态作用域,使用上要特别注意。

主要区别:词法作用域是在写代码或者定义时确定的,而动态作用域是在运行时确定的(this也是!)。词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用

参考资料


  1. 书籍:《你不知道的JavaScript:上卷》
  2. 百度百科词条:作用域
  3. cnblogs:《浅谈静态作用域和动态作用域

相关文章

  • Dynamic Scoping in Scheme

    词法作用域 vs 动态作用域 scheme是一门采用词法作用域(lexical scoping)的lisp方言,这...

  • 词法作用域

    我们知道JavaScript并不具有动态作用域,它只有词法作用域,什么是词法作用域? 一、 词法作用域 词法作用域...

  • js中的作用域

    作用域就是决定变量有效范围 作用域按决定的时期来区分可分为词法作用域和动态作用域词法作用域: 词法作用域就是作用域...

  • 前端笔试中常考题--js的函数与变量提升问题

    先谈谈作用域#### -- 什么是作用域?就是某个变量有(起)作用的范围;--词法作用域和动态作用域词法作用域:在...

  • JS基础-作用域与闭包

    1.理解词法作用域和动态作用域 词法作用域:定义在词法阶段的作用域换言之,词法作用域是由你在写代码时将变量和块作用...

  • 词法作用域

    作用域工作模式:1 词法作用域;2 动态作用域(Bash脚本、Perl中的一些模式) 2.1 词法阶段 词法作用域...

  • 「JS」变量作用域

    作用域介绍静态作用域动态作用域 JavaScript 变量作用域词法环境组成创建结构关于词法环境的问题with 语...

  • 《JavaScript 语言精粹》笔记

    U1 精华 词法作用域 词法作用域/静态作用域:作用域在词法分析阶段就确定了,不会改变 动态作用域:运行时根据程序...

  • 作用域

    词法作用域,动态作用域,全局作用域,局部作用域,函数作用域,块级作用域,有些地方还能看到隐式作用域和显示作用域。 ...

  • 词法作用域 VS 动态作用域

    作用域是个语言无关的概念,你要接触过Lisp或者Scheme等语言,应该对这个概念会非常熟悉。我在这篇文章会介绍词...

网友评论

    本文标题:词法作用域 VS 动态作用域

    本文链接:https://www.haomeiwen.com/subject/pkpbyttx.html