JavaScript 作用域不完全指北 中,我们介绍了作用域的概念以及 JavaScript 引擎、编译器和作用域的关系。作用域有两种主要的工作模型:词法作用域动态作用域。其中最为普遍的也是大多数编程语言所采用的是词法作用域,我们主要对其进行研究学习。
在传统编译语言的流程中, 程序中的一段源代码在执行之前会经历三个步骤, 统称为“编译”。

  • 分词/词法分析(Tokenizing/Lexing)

这个过程会将由字符组成的字符串分解成(对编程语言来说) 有意义的代码块, 这些代码块被称为词法单元。

  • 解析/语法分析(Parsing)

这个过程是将词法单元流(数组) 转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树。 这个树被称        为“抽象语法树”(Abstract Syntax Tree, AST)。

  • 代码生成

将“抽象语法树” 转换为可执行代码的过程称被称为代码生成。 这个过程与语言、 目标平台等息息相关。
第一个步骤也叫作词法化,词法作用域就是定义在词法阶段的作用域。简单地说,词法作用域是由你写代码时将变量和块作用域写在哪里来决定的,词法分析器处理代码时会保持作用域不变。
我们通过以下代码来分析一下词法作用域:

function foo(a){
var b = a * 2;
function bar(c){
console.log(a,b,c);
}
bar(b * 3);
}
foo(2); //2 4 12

在实例代码中,会有三个逐级嵌套的作用域。

1.包含着全局作用域,其中有一个标识符 foo

2.包含着 foo 所创建的作用域,其中有三个标识符:a,bar,b

3.包含着 bar 所创建的作用域,其中有一个标识符:c

引擎使用作用域的结构和相互之间的位置关系来查找标识符。我们在上篇文章中讲过,引擎在作用域中进行变量查找的过程,是从当前作用域逐级向外,直到遇到第一个匹配的标识符结束。
在实例代码中,引擎执行 console.log(a,b,c); 声明,并查找变量 a , b , c 的引用。首先从最内部的作用域,也就是 bar 函数的作用域开始查找,引擎无法在这里查找到变量 a ,便会到上一级所嵌套的 foo 函数作用域中进行查找。引擎在这里找到了变量 a 的引用,便会停止对变量 a 引用的查询。对 b 来说也是一样的。对 c 来说,引擎在 bar 函数作用域中就会找到它。
引擎会在作用域中找到第一个匹配的标识符时停止查找。也就是说,在多层的嵌套作用域中可以定义同名的标识符,内部的标识符会遮蔽外部的标识符,这叫作“遮蔽效应”。
词法作用域意味着作用域是由书写代码时函数的位置来决定的。编译的词法分析阶段基本能够知道全部标识符在哪里以及是如何声明的,从而预测在引擎执行代码过程中如何对它们进行查找

参考

  • 《你不知道的JavaScript》
  • 《深入理解JavaScript特性》

作者:CoderFocus

微信公众号:

声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,不妨点击一下下方的【推荐】按钮,谢谢支持。转载与引用请注明作者及出处。

JavaScript 词法作用域不完全指北的更多相关文章

  1. 网易JS面试题与Javascript词法作用域说明

    调用对象位于作用域链的前端,局部变量(在函数内部用var声明的变量).函数参数及Arguments对象都在函数内的作用域中--这意味着它们隐藏了作用域链更上层的任何同名的属性. 2010年9月14日, ...

  2. JavaScript词法作用域与调用对象

    关于 Javascript 的函数作用域.调用对象和闭包之间的关系很微妙,关于它们的文章已经有很多,但不知道为什么很多新手都难以理解.我就尝试用比较通俗的语言来表达我自己的理解吧. 作用域 Scope ...

  3. JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)

    前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...

  4. JavaScript 作用域不完全指北

    什么是作用域 对于几乎所有编程语言,最基本的功能之一就是能够存储变量的值,并且能在之后对这个值进行访问和修改.这样就会带来几个问题,这些变量存储在哪里?程序在需要的时候又是如何找到它们的?要解决这些问 ...

  5. JavaScript词法作用域经典练习题

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  6. JavaScript的作用域与作用域链

    作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期.可以说,变量和函数在什么时候可以用,什么时候被摧毁,这都与作用域有关. JavaScript中,变量的作用域有全局 ...

  7. JavaScript的作用域

    JavaScript的作用域主要是指函数的作用域,在进行结果判断的时候十分重要,如果不清楚作用域,便很有可能导致拿不到预期的结果,也就无法顺利的进行程序的编写,在经历了一系列的学习和了解之后,对相关知 ...

  8. javascript一个作用域案例分析

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. JavaScript夯实基础系列(一):词法作用域

      作用域是一组规则,规定了引擎如何通过标识符名称来查询一个变量.作用域模型有两种:词法作用域和动态作用域.词法作用域是在编写时就已经确定的:通过阅读包含变量定义的数行源码就能知道变量的作用域.Jav ...

随机推荐

  1. Android在putString和getString使用方法

    函数: putString(String key,String value); 功能:将键为key的值为value. 详细的容器详细考虑比如对于Editor 的对象来讲: 代码例如以下: 首先新建一个 ...

  2. windows 系统文件 —— 特殊文件及文件类型

    0. .mht 文件(MHTML) MHTML文件又称为聚合 HTML 文档.Web 档案或单一文件网页(聚合成单一文件).单个文件网页可将网站的所有元素(包括文本和图形)都保存到单个文件中.这种封装 ...

  3. 【Java】Java中的数据类型

    Java 语言是一种强类型语言.通俗点说就是,在 Java 中存储的数据都是有类型的,而且必须在编译时就确定其类型.Java 数据类型分为两类,如图: 在 Java 的领域里,基本数据类型变量存的是数 ...

  4. WPF依赖项属性不需要包装属性也可以工作

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  5. C++杂记:运行时类型识别(RTTI)与动态类型转换原理

    运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. ...

  6. XAML的命名空间

    原文:XAML的命名空间 一个最简单的XAML例子   <Window x:Class="WpfApplication1.MainWindow" xmlns="ht ...

  7. Mysql数据库表的自增主键ID号乱了,需要重新排列。

    Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...

  8. rdlc水晶报表在wpf里的使用

    1引用程序集 Microsoft.ReportViewer.WinForms 2 xaml 命名空间 xmlns:rv="clr-namespace:Microsoft.Reporting. ...

  9. 动态lambda 构建

    var param = Expression.Parameter(typeof(T)); var datetime1 = Expression.Constant(dt1); var datetime2 ...

  10. 加载dll、lib库(例子的代码很全)

    是关于如何加载dll或lib库的.可以看这篇bog   Qt调用dll中的功能函数点击打开链接 **************************************************** ...