简述JavaScript的scope机理

2016-02-20 00:56 11 1 收藏

今天图老师小编给大家展示的是简述JavaScript的scope机理,精心挑选的内容希望大家多多支持、多多分享,喜欢就赶紧get哦!

【 tulaoshi.com - Web开发 】

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)这个第一篇中间的内容讲得大体都是对的,但是还是搞得太复杂。倒是头尾两句话非常具有典型意义:
引用什么叫闭包?我花了很长时间来弄明白这个概念,但每次以为弄明白的时候,却又会发现其实没搞清楚。
引用这究竟是为什么,我目前还不清楚。但据说ECMA262标准给出了具体的实现方法的我没体力看了,交给大家吧。

暂时没有时间详细解说这些内容,仅把在小麦文章后面的comments记录此处。


closure还是比较容易理解的,无非是内部函数可以访问外部的变量。之所以能比较容易的支持closure,也在于JS是使用垃圾回收的,因此不存在函数局部变量生存期的问题被回收的只是局部变量符号,真正所引用的对象只要还有任何一个地方引用它无论是直接引用还是像closure那样间接引用,都不会被回收。当然,closure的间接引用也加剧了IE中内存泄露问题,此乃题外话,不赘述。

closure(闭包)、scope chain(作用域链)、lexical scope(词法作用域),三者当然不是一个概念,但是确实是有紧密联系的。具体来说,JS语言是以scope chain的方式来实现lex scope和closure的。所以就算搞不懂scope chain,也不妨碍你使用JS。

1. scope chain是一种实现手段,具体来说,它是一种name lookup的检索机制。

2. lexical scope是一种作用域机制,它很好理解。因为lex scope取决于源代码,所以通常编译器可以进行静态分析来确定每个标识符实际的引用。实际上lexical scope因此也称为static scope。

3. 其实JS并非完全的lexical scope。因为有with和eval这两个特例。所以说JS是lexical scope实际上是说它的scope机制非常接近于lexical scope。

4. 因此JS引擎通常不使用静态分析,而且只使用静态分析是无法实现with的语义的!JS使用类似dynamic scope的技术,区别在于通常dynamic scope的bindings堆栈是全局的,而JS为每个execution context都单独设置一个bindings堆栈,也就是所谓的scope chain。

5. 结论:可以把JS的scope看做一个用scope chain机制实现的近似lexical scope。


Updates:
关于with/eval对于lexical scope的影响,可以看这位用scheme实现JS引擎的同志的说法:
引用...But the real subtlety comes in with the with (dynamically add a computed object value to the runtime environment as a new environment frame) and eval constructs...
... So outside of a with, you get normal, efficient lexical scope; inside a with, you get stupid, slow, dynamic scope...

来源:http://www.tulaoshi.com/n/20160220/1632865.html

延伸阅读
标签: Web开发
使用JavaScript可以创建自己的对象。虽然JavaScript内部和浏览器本身的功能已十分强大,但JavaScript还是提供了创建一个新对象的方法。 使其不必像超文本标识语言那样,求于或其它多媒体工具,就能完成许多复杂的工作。 在JavaScript中创建一个新的对象是十分简单的。首先它必须定义一个对象,而后再为该对象创建一个实例。这个实例就是...
标签: Web开发
虽然 JavaScript 与Java有紧密的联系,但却是两个公司开发的不同的两个产品。Java是SUN公司推出的新一代面向对象的程序设计语言,特别适合于Internet应用程序开发;而JavaScript是Netscape公司的产品,其目的是为了扩展Netscape Navigator功能,而开发的一种可以嵌入Web页面中的基于对象和事件驱动的解释性语言,它的前身是Live Script;而Ja...
    关于预激综合征的发生机理,近年来的研究证实:主要是由于在心房与心室之间存在着附加的传导径路,该径路的传导速度远较正常的房室传导为快。当通过正常房室传导的心房激动尚未到达心室之间,该激动已通过附加的房室径路迅速到达心室,因而使部分心室肌提前开始激动。目前,在组织学上已经证实的附加径路有肯氏(kent)束...
标签: Web开发
上次写的一篇《JavaScript 数组的 uniq 方法》,发现代码的问题还是存在。比如如果数组内有 undefined 元素就无法过滤等。 昨天看见 Lazy 兄弟重新更新了函数,现在他是这样子写的: Array.prototype.uniq = function() {     var resultArr = [], ...
标签: Web开发
javascript的作用域是词法作用域(lexical scope or static scope),也就是说作用域链在定义的时候就确定了。也提到eval、with会扰乱作用域链(dynamic scope)。 eval IE下:运行eval()会受当前作用域限制,运行execScript()则无视当前作用域,直接在全局作用域下执行。 Firefox下:eval()和window.eval()效果不一样,这...

经验教程

295

收藏

98
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部