你不知道的JavaScript——第一章:作用域是什么?
编译原理
JavaScript事实上是一门编译语言,但与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植。
任何JavaScript代码片段在执行前都要进行编译(通常就在执行前)。
在传统编译语言的流程中,程序中的一段源代码在执行之前会经历三个步骤,统称为“”编译“”。
1.分词/词法分析(Tokenizing/Lexing)
将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元。
分词(tokenizing)和词法分析(lexing)之间的区别:
主要差异在于词法单元的识别是通过有状态还是无状态的方式进行的。
如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时,调用的是有状态的解析规则,那么这个过程就被称为词法分析。
2.解析/语法分析(parsing)
将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树。这个树被称为“”抽象语法树“”(Abstract Syntax Tree,AST)。
3.代码生成
将AST转换为可执行代码的过程被称为代码生成。
理解作用域:
引擎:
从头到尾负责整个JavaScript程序的编译及执行过程。
编译器:
引擎的好朋友之一,负责语法分析及代码生成等脏活累活
作用域:
引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。
引擎的查找 LHS和RHS
当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。
RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是试图找到变量的容器本身,从而可以对其赋值。
RHS并不是真正意义上的“赋值操作符的右侧”,更准确地说是“非左侧”。
赋值操作的目标是谁(LHS)??
谁是赋值操作的源头(RHS)??
作用域嵌套
遍历嵌套作用域链的规则:引擎从当前的执行作用域开始查找变量,如果找不到,就向上一级继续查找。当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都会停止。
异常
如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出referenceError异常。值得注意的是,referenceError是非常重要的异常类型。
当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎,前提是程序运行在非“严格模式”下。
在严格模式中LHS查询失败时,并不会创建并返回一个全局变量,引擎会抛出同RHS查询失败时类似的referenceError异常。
若RHS查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或者引用null或undefined类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫做TypeError。
ReferenceError同作用域判别失败相关,而typeError则代表作用域判别成功了,但是对结果的操作是非法或不合理的。
小结:
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果目的是获取变量的值,就会使用RHS查询。赋值操作符会导致LHS查询。=操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。
JavaScript引擎首先会在代码执行前对其进行编译,在这个过程中,像var a=2这样的声明会被分解成两个独立的步骤:
1.首先,var a 在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。
2.接下来,a=2会查询(LHS查询)变量a并对其进行赋值。
LHS和RHS查询都会在当前执行作用域中开始,如果有需要(也就是说它们没有找到所需的标识符),就会向上级作用域继续查找目标标识符,这样每次上升一级作用域(一层楼),最后抵达全局作用域(顶层),无论找到或没找到都将停止。
不成功的RHS引用会导致抛出referenceError异常,不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出referenceError异常(严格模式下)。
你不知道的JavaScript——第一章:作用域是什么?的更多相关文章
- 你不知道的javaScript上卷(第一章 作用域是什么)
在写这篇博客时这本书我已经是看过一遍了,为了加深印象和深入学习于是打算做这系列的前端经典书籍导读博文,大家如果觉得这本书讲的好可以自己买来看看,我是比较喜欢看纸质版书的,因为这样才有读书的那种感觉. ...
- 你不知道的JavaScript——第二章:this全面解析
1调用位置 调用栈:为了到达当前执行位置所调用的所有函数. function baz(){ //当前调用栈:baz //因此,当前调用位置是全局作用域 console.log('baz'); bar( ...
- JavaScript 第一章总结
A quick dip into javascipt The way JavaScript works HTML 用一系列的 markup 来呈现整个 content 的 structure.CSS ...
- 重温Javascript第一章
一.script标签 script标签有6个属性,其中一个废弃,五个可选. 按照传统的写法,<script>的标签都是放在<head>元素中,但是在<head>中包 ...
- 【读书笔记】你不知道的JavaScript(上卷)--作用域是什么
第一章 作用域 1.理解作用域 几个名词的介绍 引擎:从头到尾负责整个JavaScript程序的编译及执行过程 编译器:负责语法分析及代码生成器等脏活累活 作用域:负责收集并维护由所有声明的标识符(变 ...
- 你不知道的JavaScript(上)作用域与闭包
第一部分 作用域与闭包 第一章 作用域是什么 1.作用域 变量赋值操作会执行两个动作:首先编译器会在当前作用域中声明一个变量(如果之前没有声明过), 然后会在运行时引擎会在作用域中查找该变量,找到就会 ...
- 《你不知道的js》 ------1.作用域是什么
相关定义 引擎:从头到尾负责整个JavaScript程序的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规 ...
- 你不知道的JavaScript 上卷 2/11
第一部分——作用域和闭包 第一章 作用域是什么 1.几乎所有编程语言最基本的功能之一,就是能够储存变量当中的值,并且能在之后对这个值进行访问或修改.事实上,正是这种储存和访问变量的值的能力将状态带给了 ...
- 《你不知道的JavaScript》第一部分:作用域和闭包
第1章 作用域是什么 抛出问题:程序中的变量存储在哪里?程序需要时,如何找到它们? 设计 作用域 的目的:为了更好地存储和访问变量. 作用域:根据名称查找变量的一套规则,用于确定在何处以及如何查找变量 ...
随机推荐
- NOsql总结
NOsql总结 1.存储: 任意格式的数据:值对存储,列存储,文档存储,图形数据库 灵活的表结构支持:类型动态.scheme动态: 灵活的存储形式:列存储: 弱关系:NoSQL数据库种类繁多,但是一个 ...
- tensorflow中的name_scope, variable_scope
在训练深度网络时,为了减少需要训练参数的个数(比如LSTM模型),或者是多机多卡并行化训练大数据.大模型等情况时,往往就需要共享变量.另外一方面是当一个深度学习模型变得非常复杂的时候,往往存在大量的变 ...
- node访问oracledb的环境搭建
关于安装oracleDB环境官网说明地址: https://oracle.github.io/node-oracledb/INSTALL.html 环境搭建所需软件和文档的压缩包 链接: https: ...
- CentOS自带定时任务crontab
设置定时任务规则,crontab -e,如下示例为每一分钟执行一次脚本 在脚本中写入内容时需注意路径,可以写绝对路径,也可以按照如下形式 exepath=$(cd "$(dirname &q ...
- PAT A1052 Linked List Sorting (25 分)——链表,排序
A linked list consists of a series of structures, which are not necessarily adjacent in memory. We a ...
- web 项目:解决插入 MySQL 数据库时中文乱码问题
背景:在做 javaweb 项目的时,前台传递的中文最后插入数据库的时候总是出现乱码现象. 解决方案 A.不管是使用 Idea.eclipse,确定自己的项目所使用的字符集是 UTF-8. B ...
- DataHub使用小结(一)——概述
一.概念 1.什么是DataHub DataHub是流式数据(Streaming Data)的处理平台,提供对流式数据的发布(Publish),订阅(Subscribe)和分发功能, 可以轻松构建基于 ...
- JFrame2
package com.fxb.gui; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.TextFie ...
- 史上最全面的Elasticsearch使用指南
Elasticsearch使用指南 Elasticsearch使用指南 前言 ES是什么 什么是全文检索 ES的应用场景 ES的存储结构 第一章:安装 1.下载 2.解压 3.配置 4.启动 5.查看 ...
- (5)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 熔断降级(Polly)
一. 什么是熔断降级 熔断就是“保险丝”.当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成“雪崩”,或者大量的超时等待导致系统卡死. 降级的目的是当某个服务提供者发 ...