`
hax
  • 浏览: 962955 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

简述JavaScript的scope机理

    博客分类:
  • JS
阅读更多
小麦正在写《作用域链 词法作用域 与 闭包》系列。这个第一篇中间的内容讲得大体都是对的,但是还是搞得太复杂。倒是头尾两句话非常具有典型意义:
引用
什么叫闭包?我花了很长时间来弄明白这个概念,但每次以为弄明白的时候,却又会发现其实没搞清楚。

引用
……这究竟是为什么,我目前还不清楚。但据说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...

4
0
分享到:
评论
4 楼 hax 2011-09-01  
igotti 写道
彻底理解closure和scope chain是在看到周老师的javascript语言精髓(虽然作者本意不是讲解js。。)


爱民的书在讲解closure方面有些小问题,你可以等他这本书的第二版出来,应该会讲解的更加准确。
3 楼 hax 2011-09-01  
s79 写道
那new Function("var ...")这类的呢?是和eval、with并列,还是和eval类似?突然想到,没深入研究过,请点拨~


new Function中的代码其上层作用域是global的,所以不会受到其他代码的with约束,其内部的var声明仅限于函数scope,而其内部的eval仅限于函数scope和global scope。通常能用new Function达到的效果,可尽量不要用eval来实现。
2 楼 igotti 2011-08-20  
彻底理解closure和scope chain是在看到周老师的javascript语言精髓(虽然作者本意不是讲解js。。)
1 楼 s79 2009-11-29  
那new Function("var ...")这类的呢?是和eval、with并列,还是和eval类似?突然想到,没深入研究过,请点拨~

相关推荐

    javascript原理

    JavaScript原理详解 JavaScript是一种强大的脚本语言,起源于Netscape公司开发的Livescript,随着Web技术的发展,尤其是在Navigator 2.0中引入Java小程序支持后,Livescript更名为JavaScript,成为一种独立的语言。...

    JavaScript常用语句及语言参考

    JavaScript是一种广泛应用于Web开发的脚本语言,它在浏览器端运行,为网页添加交互性,使得用户能够与页面进行动态沟通。这篇文档将深入探讨JavaScript的常用语句和语言参考,帮助初学者建立坚实的基础。 一、变量...

    javascript 函数介绍

    1. 函数的定义和调用 在JavaScript中,定义函数最常用的方法就是调用function语句。该语句是由function关键字构成的,它后面紧跟的是: Ø 函数名 Ø 一个用括号的参数列表,参数是可选的,参数是用逗号分隔开 Ø ...

    简述JavaScript提交表单的方式 (Using JavaScript Submit Form)

    主要介绍了简述JavaScript提交表单的方式 (Using JavaScript Submit Form)的相关资料,需要的朋友可以参考下

    JAVASCRIPT编辑环境

    一个特别有用的学习Javascript的软件

    html+css+javascript+jQuery简述

    html+css+javascript+jQuery简述

    javascript介绍

    介绍JavaScript,功能作用,以及学习流程

    简述JavaScript中正则表达式的使用方法

    在JavaScript中,正则表达式是通过RegExp对象来实现的,允许执行复杂的文本操作和验证。接下来我们将详细介绍JavaScript中正则表达式的使用方法。 首先,要创建一个正则表达式对象,有两种方式: 1. 使用RegExp()...

    AJAX简介 异步 JavaScript 及 XML(Asynchronous JavaScript And XML)

    AJAX,全称为异步 JavaScript 和 XML,是2005年由Google引领的一种Web开发技术。它并不是一种全新的编程语言,而是利用现有的Web标准来构建更高效、更具交互性的网页应用。通过AJAX,开发者能够在用户与服务器间进行...

    简述JavaScript对传统文档对象模型的支持

    JavaScript对传统文档对象模型(DOM)的支持是其在Web开发中的核心特性之一。DOM是一种跨平台的接口,它允许脚本语言和程序访问和修改文档的结构、样式和内容。JavaScript通过DOM可以实现对HTML或XML文档的动态操作...

    JavaScript入门经典(第4版) Beginning JavaScript

    - **Web发展历史**:简述了Web的发展历程,介绍了静态网页向动态网页转变的过程。 - **JavaScript的起源**:讲述了JavaScript是如何诞生的,以及它如何逐渐成为Web开发中不可或缺的一部分。 - **JavaScript的作用**...

    javascript的分支结构

    javascript的分支结构

    动态HTML特征简述及利用Javascript在页面中实现动态效果机制分析与实例.pdf

    例如,可以使用JavaScript来改变图片的显示、创建动画、添加和删除页面元素,或者实现下拉菜单和弹出窗口等功能。 4. **动态字体**:动态HTML允许在页面中使用和操作字体,包括字体的大小、颜色、样式等,可以在...

    javascript完全自学手册 光盘

    9. **前端框架与库**:简述React、Vue、Angular等现代前端框架的基本概念和应用场景,以及它们如何简化JavaScript开发。 10. **性能优化**:学习如何编写高性能的JavaScript代码,包括减少DOM操作、避免全局变量、...

    前端发展简介

    JavaScript的诞生进一步推动了这一进程,实现了客户端的计算任务,比如表单验证,减轻了服务器的压力。1996年的iframe标签允许异步加载局部内容,1999年XMLHttpRequest的引入则预示着Ajax技术的崛起,它实现了页面...

    javascript实现rsa加解密

    下面简述一下使用JavaScript进行RSA加解密的步骤: 1. **生成密钥对**:首先,我们需要生成一对RSA密钥。这可以通过调用特定库的函数完成,如`OpenSSL`的`openssl genpkey`命令可以生成PEM格式的密钥对。在...

    简述JavaScript的正则表达式中test()方法的使用

    JavaScript是一种广泛使用的编程语言,它在网页开发中扮演着重要的角色。其中,正则表达式是JavaScript中用来进行字符串处理的强大工具,它能够对字符串进行复杂的搜索、匹配和替换操作。在JavaScript正则表达式中,...

    在B_S开发中经常用到的javaScript技术

    【JavaScript在B/S开发中的应用】 JavaScript是一种广泛应用于B/S(Browser/Server,浏览器/服务器)架构中的客户端脚本语言,它在网页交互、数据验证、动态效果等方面发挥着重要作用。以下将详细介绍在B/S开发中...

Global site tag (gtag.js) - Google Analytics