第1章 作用域是什么
2016-04-14 16:13
423 查看
作用域:是说明如何存储变量,以及如何查找这些变量的规则;
编译原理
编译过程
分词或词法分析(tokening或lexing)
将代码字符串分解成有意义的代码块,这些代码块称为词法单元;
解析或语法分析(parsing)
将所有词法单元转换成由元素逐级嵌套组成的抽象语法树AST,AST代表了程序的语法结构;
代码生成
将AST转换为一组机器指令;
javascript的编译
javascript执行之前是进行编译的,编译发生在执行之前的很短时间之内;
作用域
术语
引擎:负责整个javascript程序的编译和执行过程;
编译器:负责语法分析和代码生成;
作用域:负责收集并维护对所有声明变量的查询,按照规则确定当前执行的代码对这些变量的访问权限;
变量声明并赋值的过程
引擎在执行var a=2;语句时,包含两个过程:
var a由编译器进行处理,编译器会查询作用域中是否已存在该变量:
如果变量不存在会在当前作用域中声明新变量,命名为a;
如果变量已存在,声明会被忽略;
编译器会将a=2转换为机器码,并由引擎运行;
引擎在运行该代码时,首先查询作用域是否存在a变量,如果存在就会使用该变量,将2赋值给a;
如果不存在a变量,引擎会继续查找,如果最终没有找到该变量,将抛出异常;
LHS查询和RHS查询
RHS:简单的查询变量的值;
当变量作为赋值的源时进行RHS查询;
LHS:查找变量的内存地址(?)以便对其进行赋值;
当变量作为赋值目标时,执行LHS查询;
执行LHS查询时,并不关系变量本身的值;
在执行变量赋值如var b=a时:
对a进行RHS查询,取得a的值;
再对b进行LHS查询,取得b的内存地址,并将a的值保存到该地址;
函数调用时,首先对函数进行RHS查询,实参到形参的传递涉及对形参的LHS查询;
function foo(a){}不能理解成var foo=function(a){}这样的LHS查询和赋值形式;
作用域链
当一个函数嵌套在另一函数中时,就发生了作用域的嵌套,在当前作用域中无法找到某个变量时,引擎就会在外层作用域中继续查找,直至到达全局作用域,这些嵌套的作用域称为作用域链;
异常
在变量未声明时,进行两种查询的行为是不一样的;
对一个未声明的变量进行RHS查询时,引擎会抛出ReferenceError异常;
对一个未声明的变量进行LHS查询,会导致在全局作用域创建该变量;
只在非严格模式下可行,在严格模式下对未声明变量进行LHS查询,同样会导致ReferenceError异常;
对一个变量成功进行了RHS查询之后,如果对变量值进行不合理的操作会导致TypeError异常;
编译原理
编译过程
分词或词法分析(tokening或lexing)
将代码字符串分解成有意义的代码块,这些代码块称为词法单元;
解析或语法分析(parsing)
将所有词法单元转换成由元素逐级嵌套组成的抽象语法树AST,AST代表了程序的语法结构;
代码生成
将AST转换为一组机器指令;
javascript的编译
javascript执行之前是进行编译的,编译发生在执行之前的很短时间之内;
作用域
术语
引擎:负责整个javascript程序的编译和执行过程;
编译器:负责语法分析和代码生成;
作用域:负责收集并维护对所有声明变量的查询,按照规则确定当前执行的代码对这些变量的访问权限;
变量声明并赋值的过程
引擎在执行var a=2;语句时,包含两个过程:
var a由编译器进行处理,编译器会查询作用域中是否已存在该变量:
如果变量不存在会在当前作用域中声明新变量,命名为a;
如果变量已存在,声明会被忽略;
编译器会将a=2转换为机器码,并由引擎运行;
引擎在运行该代码时,首先查询作用域是否存在a变量,如果存在就会使用该变量,将2赋值给a;
如果不存在a变量,引擎会继续查找,如果最终没有找到该变量,将抛出异常;
LHS查询和RHS查询
RHS:简单的查询变量的值;
当变量作为赋值的源时进行RHS查询;
LHS:查找变量的内存地址(?)以便对其进行赋值;
当变量作为赋值目标时,执行LHS查询;
执行LHS查询时,并不关系变量本身的值;
在执行变量赋值如var b=a时:
对a进行RHS查询,取得a的值;
再对b进行LHS查询,取得b的内存地址,并将a的值保存到该地址;
函数调用时,首先对函数进行RHS查询,实参到形参的传递涉及对形参的LHS查询;
function foo(a){}不能理解成var foo=function(a){}这样的LHS查询和赋值形式;
作用域链
当一个函数嵌套在另一函数中时,就发生了作用域的嵌套,在当前作用域中无法找到某个变量时,引擎就会在外层作用域中继续查找,直至到达全局作用域,这些嵌套的作用域称为作用域链;
异常
在变量未声明时,进行两种查询的行为是不一样的;
对一个未声明的变量进行RHS查询时,引擎会抛出ReferenceError异常;
对一个未声明的变量进行LHS查询,会导致在全局作用域创建该变量;
只在非严格模式下可行,在严格模式下对未声明变量进行LHS查询,同样会导致ReferenceError异常;
对一个变量成功进行了RHS查询之后,如果对变量值进行不合理的操作会导致TypeError异常;
相关文章推荐
- Whole life
- 使序列有序的最少交换次数
- java-乱码总结
- leetcode 135. Candy
- Android 主流网络请求框架 Android-async-http
- ffmpeg arm编译
- [算法学习]20150414.3.快排
- 统计利用先序遍历创建的二叉树的宽度
- 数据库学习整理
- 码农小汪-设计模式之-Builder模式
- ios 内置支付宝
- inline函数详解
- 对于数据库操作可能会遇到的问题(空值问题以及出现的参数不能被重复使用问题)
- oc知道经纬度求位置
- 浅谈算法和数据结构: 七 二叉查找树
- 微软官方补丁6B BUG造成WIN7系统蓝屏解决方案
- 8.2检测图像中的角点
- 微信支付异步回调的坑,调用成功了回调地址却没有数据
- LeetCode 142 Linked List Cycle II
- 队列——链表实现