美文网首页ES 6写法You don't know JavaScriptJavascript
你不懂JS:作用域与闭包 附录A:动态作用域

你不懂JS:作用域与闭包 附录A:动态作用域

作者: HetfieldJoe | 来源:发表于2016-08-12 09:30 被阅读325次

官方中文版原文链接

感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大奖:点击这里领取

在第二章中,作为与JavaScript中(事实上,其他大多数语言也是)作用域的工作方式模型 —— “词法作用域”的对比,我们谈到了“动态作用域”。

我们将简单地检视动态作用域,来彻底说明这种比较。但更重要的是,对于JavaScript中的另一种机制(this)来说动态作用域实际上是它的一个近亲表兄,我们将在本系列的“this与对象原型”中详细讲解这种机制。

正如我们在第二章中看到的,词法作用域是一组关于 引擎 如何查询变量和它在何处能够找到变量的规则。词法作用域的关键性质是,它是在代码编写时被定义的(假定你不使用eval()with作弊的话)。

动态作用域看起来在暗示,有充分的理由,存在这样一种模型,它的作用域是在运行时被确定的,而不是在编写时静态地确定的。让我们通过代码来说明这样的实际情况:

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

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

var a = 2;

bar();

foo()的词法作用域中指向a的RHS引用将被解析为全局变量a,它将导致输出结果为值2

相比之下,动态作用域本身不关心函数和作用域是在哪里和如何被声明的,而是关心 它们是从何处被调用的。换句话说,它的作用域链条是基于调用栈的,而不是代码中作用域的嵌套。

所以,如果JavaScript拥有动态作用域,当foo()被执行时,理论上 下面的代码将得出3作为输出结果。

function foo() {
    console.log( a ); // 3  (不是 2!)
}

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

var a = 2;

bar();

这怎么可能?因为当foo()不能为a解析出一个变量引用时,它不会沿着嵌套的(词法)作用域链向上走一层,而是沿着调用栈向上走,以找到foo()从何处 被调用的。因为foo()是从bar()中被调用的,它就会在bar()的作用域中检查变量,并且在这里找到持有值3a

奇怪吗?此时此刻你可能会这样认为。

但这可能只是因为你仅在拥有词法作用域的代码中工作过。所以动态作用域看起来陌生。如果你仅使用动态作用域的语言编写过代码,它看起来就是很自然的,而词法作用域将是个怪东西。

要清楚,JavaScript 实际上没有动态作用域。它拥有词法作用域。简单明了。但是this机制有些像动态作用域。

关键的差异:词法作用域是编写时的,而动态作用域(和this)是运行时的。词法作用域关心的是 函数在何处被声明,但是动态作用域关心的是函数 从何处 被调用。

最后:this关心的是 函数是如何被调用的,这揭示了this机制与动态作用域的想法有多么紧密的关联。要了解更多关于this的细节,请阅读 “this与对象原型”。

相关文章

  • 你不懂JS:作用域与闭包 附录A:动态作用域

    官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...

  • 你不懂JS:作用域与闭包

    你不懂JS:作用域与闭包 第五章:作用域闭包 希望我们是带着对作用域工作方式的健全,坚实的理解来到这里的。 我们将...

  • js 闭包

    一、js 作用域 讲闭包首先就要理解 js 的作用域。再 ES5 中,js 有两种作用域,全局作用域和函数作用域(...

  • 你不懂JS:作用域与闭包

    你不懂JS:作用域与闭包 第三章:函数与块儿作用域 正如我们在第二章中探索的,作用域由一系列“气泡”组成,这些“气...

  • js闭包详解

    1.什么是闭包? 要了解什么是闭包,首先你要了解作用域。 js的作用域分两种,全局作用域和局部作用域。 我们知道在...

  • 你不懂JS:作用域与闭包

    你不懂JS:作用域与闭包 第二章:词法作用域 在第一章中,我们将“作用域”定义为一组规则,它主宰着 引擎 如何通过...

  • js闭包的理解

    什么是闭包 通俗的来讲,个人觉得闭包就是延长变量作用域的函数。众所周知js的作用域分为全局作用域和链式作用域。在函...

  • 作用域和闭包

    目录 概述 作用域编译过程词法作用域全局作用域函数作用域 闭包循环和闭包闭包的用途性能 总结 概述 作用域和闭包一...

  • JavaScript 函数闭包(colsure)

    理解闭包,你首先必须理解JS的变量作用域,JavaScript作用域和作用域链。 ES6之前,变量的作用域分为全局...

  • 2018-01-07 关于javascript闭包和作用域的理解

    关于 javascript 闭包的一些思考 作用域 词法作用域 函数作用域 块作用域 闭包 什么是作用域? 作用域...

网友评论

    本文标题:你不懂JS:作用域与闭包 附录A:动态作用域

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