作用域的由来
编程语言的基本功能就是能够存储变量当中的值,并且能够对其进行访问和修改,将变量引入程序会引起几个有意思的问题?
1.变量储存在哪里?
2.程序需要的时候如何找到他们?
//这些问题说明需要一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则就是作用域!
//那么接着问题又来了,我们如何设置这些作用域的规则呢?
编译原理
- JavaScript是一门编译语言,但是它又和传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植,尽管如此JavaScript引起进行编译的步骤和传统的编译语言非常相似
编译语言:在代码执行前有一个编译过程,将代码解释成机械语言,以后再用这段代码,就不用再翻译了
解释语言:在代码运行的时候,边翻译边执行,明显这种方式的代码运行速度是比较慢的
- 传统编译语言,程序中的一段源代码在执行之前要经历三个步骤,统称"编译"
词法分析,语法分析,代码生成
- 任何JavaScript代码在执行之前都进行编译,var a =2 ;这句简单的代码,在运行前,浏览器中的JavaScript编译器,会对它进行编译,然后执行
//计算机是一个机器,机器只认识0和1,任何高级的语言都需要编译器来把代码翻译成机器语言,机器才能运行.
//互联网技术就像一座大厦,大厦是一砖一瓦由低到高建立起来的 - 浏览器中主要有以下几个角色
//JavaScript引擎,JavaScript编译器,作用域,
//JavaScript引擎负责代码的编译和执行工作
//JavaScript编译器负责代码的编译工作
//作用域负责和两者沟通的角色
var a =2 ;就以这句简单的代码为例
//遇到var a的时候,编译器会询问作用域是否已经有一个该名称的变量存在于同一个作用域的集合中?如果是,编译器会忽略该声明,继续进行编译,否则它会要求作用域在当前作用域的集合中声明一个新的变量,并命名为a
//接下来编译器会为引起生成运行时所需要的代码,这些代码被用来处理a=2这个赋值操作,引擎运行时首先询问作用域,在当前的作用域集合中是否存在一个叫做a的变量?如果是引擎就会使用这个变量,否则,引擎会继续向上索引查找该变量
//如果引擎找到了a变量,就会将2赋值给它,否则引擎就会抛出异常
- 总结:
变量的赋值操作会执行两个动作,首先编译器会在作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值
编辑器有话说
- 编译器在编译过程的第二部中生成了代码,引擎执行时,会通过查找变量a来判断它是否声明过,查找的过程由作用域来协助,但是引擎执行怎样的查找,会影响最终的查找结果
- 当变量出现在复制操作的左侧时,进行LHS查询,出现在右侧时进行RHS查询
//区别在于,RHS查找,与简单的查找某个变量的值没有区别,而LHS查找是试图
找到变量的容器本身,从这个角度上来说,RHS并不是真的意义上的赋值操作的右侧,更准确来说是非左侧
//更准确地说:赋值操作的目标是谁(LHS)
谁是赋值操作的源头(RHS)
作用域嵌套
- 作用域是根据名称查找变量的一套规则
- 实际情况中,当一块或函数嵌套在另一块或函数中时,就会发生作用域的嵌套,因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,知道找到该变量或抵达最外层的作用域(全局作用域),如果还是没有找到就停止