词法作用域

上次说到作用域,将其定义为一套规则,这套规则用来管理引擎如何在当前作用 域以及嵌套的子作用域中根据标识符名称进行变量查找。

作用域共有两种主要的工作模型。第一种是最为普遍的,被大多数编程语言所采用的词法作用域。另外一种叫作动态作用域,仍有一些编

程语 言在使用(比如 Bash 脚本、Perl 中的一些模式等)。

大部分标准语言编译器的第一个工作阶段叫作词法化(也叫单词化)。词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过

程,还会赋予单词语义。

那么什么是词法作用域 ?

词法作用域就是定义在词法阶段的作用域。换句话说,词法作用域是由你在写 代码时将变量和块作用域写在哪里来决定的,因此当词法分析

器处理代码时会保持作用域不变 。

查找

作用域查找会在找到第一个匹配的标识符时停止。在多层的嵌套作用域中可以定义同名的 标识符,这叫作“遮蔽效应”(内部的标识符“遮蔽”

了外部的标识符)。抛开遮蔽效应, 作用域查找始终从运行时所处的最内部作用域开始,逐级向外或者说向上进行,直到遇见 第一个匹配的标

识符为止。

1.全局变量会自动成为全局对象(比如浏览器中的 window 对象)的属性,因此 可以不直接通过全局对象的词法名称,而是间接地通过对全局

对象属性的引 用来对其进行访问。

window.a

通过这种技术可以访问那些被同名变量所遮蔽的全局变量。但非全局的变量 如果被遮蔽了,无论如何都无法被访问到。

2.无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处 的位置决定。

3.词法作用域查找只会查找一级标识符 。

小结:

词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。编译的词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的,

从而能够预测在执行过程中如何对它们进行查找。

欺骗词法

JavaScript 中有两个机制可以“欺骗”词法作用域:eval(..) 和 with。前者可以对一段包含一个或多个声明的“代码”字符串进行演算,并借此

来修改已经存在的词法作用域(在 运行时)。后者本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作用域中的标识符来

处理,从而创建了一个新的词法作用域(同样是在运行时)。

JavaScript中 还 有 其 他 一 些 功 能 效 果 和eval(..)很 相 似。setTimeout(..)和 setInterval(..) 的第一个参数可以是字符串,字符串

的内容可以被解释为一段动态生成的 函数代码。这些功能已经过时且并不被提倡。不要使用它们!

new Function(..) 函数的行为也很类似,最后一个参数可以接受代码字符串,并将其转 化为动态生成的函数(前面的参数是这个新生成的函数

的形参)。这种构建函数的语法比 eval(..) 略微安全一些,但也要尽量避免使用。

with 通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。with 可以将一个没有或有多个属性的对象处

理为一个完全隔离的词法作用域,因此这个对 象的属性也会被处理为定义在这个作用域中的词法标识符。

尽管 with 块可以将一个对象处理为词法作用域,但是这个块内部正常的 var 声明并不会被限制在这个块的作用域中,而是被添加到 with 所处

的函数作用域中。

eval(..) 函数如果接受了含有一个或多个声明的代码,就会修改其所处的词法作用域,而 with 声明实际上是根据你传递给它的对象凭空创建了

一个全新的词法作用域。

eval(..) 和 with的副作用是引擎无法在编译时对作用域查找进行优化,因为引擎只能谨慎地认为这样的优化是无效的。使用这其中任何一个机制

都将导致代码运行变慢。不要使用它们。

你不知道的JavaScript 二的更多相关文章

  1. 《你不知道的JavaScript》整理(二)——this

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,这次研究了一下“this”. 当一个函数被调用时,会创建一个活动记录(执行上下文). 这个记录会包含函 ...

  2. 读《你不知道的JavaScript(上卷)》后感-作用域闭包(二)

    github原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们, ...

  3. JS闭包—你不知道的JavaScript上卷读书笔记(二)

    关于闭包,初学者会被绕的晕头转向,在学习的路上也付出了很多精力来理解. 让我们一起来揭开闭包神秘的面纱. 闭包晦涩的定义 看过很多关于闭包的定义,很多讲的云里雾里,晦涩难懂.让不少人以为闭包是多么玄乎 ...

  4. 《你不知道的JavaScript》整理(一)——作用域、提升与闭包

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,里面分析了很多基础性的概念. 可以更全面深入的理解JavaScript深层面的知识点. 一.函数作用域 ...

  5. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  6. JavaScript中的this(你不知道的JavaScript)

    JavaScript中的this,刚接触JavaScript时大家都在大肆渲染说其多么多么的灵巧重要,然而自己并不关心:随着自己对JavaScript一步步深入了解,突然恍然大悟,原来它真的很重要!所 ...

  7. 读《你不知道的JavaScript(上卷)》后感-浅谈JavaScript作用域(一)

    原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们,也入手看看这 ...

  8. 《你不知道的 JavaScript 上卷》 学习笔记

    第一部分: 作用域和闭包 一.作用域 1. 作用域:存储变量并且查找变量的规则 2. 源代码在执行之前(编译)会经历三个步骤: 分词/此法分析:将代码字符串分解成有意义的代码块(词法单元) 解析/语法 ...

  9. JavaScript作用域闭包(你不知道的JavaScript)

    JavaScript闭包.是JS开发project师必须深入了解的知识. 3月份自己曾撰写博客<JavaScript闭包>.博客中仅仅是简单阐述了闭包的工作过程和列举了几个演示样例,并没有 ...

随机推荐

  1. jquery 事件绑定以及解绑定

    var targetSelect = $("#@(Perfix)tbData tbody tr select[data-target]"); targetSelect.off(&q ...

  2. 程序员书单_java学习基础编程篇

    Java程序设计语言.(美国)阿诺德.清晰版 http://download.csdn.net/detail/shenzhq1980/9076093 JAVA2核心技术第1卷.基础知识7th.part ...

  3. HackerRank "Morgan and a String"

    I saw the same sub-problem in LeetCode, and there exists a O(n) neat greedy solution: for _ in range ...

  4. 剑指offer系列22--二叉树中和为某一值的路径

    22[题目]输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径. * 路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径 * [思路]只要从根结点到叶结点一条一条遍 ...

  5. 【转】双机高可用、负载均衡、MySQL(读写分离、主从自动切换)架构设计

    架构简介 前几天网友来信说帮忙实现这样一个架构:只有两台机器,需要实现其中一台死机之后另一台能接管这台机器的服务,并且在两台机器正常服务时,两台机器都能用上.于是设计了如下的架构.此架构主要是由kee ...

  6. erlang实现ssh

    借鉴自http://blog.csdn.net/the__one/article/details/6567443和http://blog.yufeng.info/archives/1509 单命令启动 ...

  7. C语言每日一题之No.1

    鉴于在学校弱弱的接触过C,基本上很少编程,C语言基础太薄弱.刚好目前从事的是软件编程,难度可想而知.严重影响工作效率,已无法再拖下去了.为此,痛下决心恶补C语言.此前只停留在看书,光看好像也记不住,C ...

  8. 单源最短路径——Floyd算法

    正如我们所知道的,Floyd算法用于求最短路径.Floyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3). Floyd算法的基本思想如下:从任意 ...

  9. (C# Debug)A first chance exception of type 'System.ArgumentException' occurred in System.Data.dll

    Debug 模式下运行程序的时候,Output 窗口出来个错误“A first chance exception of type 'System.ArgumentException' occurred ...

  10. OAF_EO系列5 - Update详解和实现(案例)

    2014-06-14 Created By BaoXinjian