第一章 作用域是什么
提示:这里只是作者的学习,如果出现理解错误欢迎指正
1.1 编译原理
1.2 理解作用域
1.3 作用域嵌套
1.4 异常
1.5 小结
文章目录
前言
随着前端的不断发展,这项行业也越来越卷,虽然面试的时候都会问JS,但是他们问的JS都足够刁钻,所以本文就介绍了《你不知道的JavaScript》这一书,以卷治卷。
概念:几乎所有的编程语言都有的基本功能就是能储存变量当中的值,并且在之后能对当前值进行访问和修改。为了方便的找到这些变量,就会设置一套良好的规则来存储变量,这套规则被称为作用域
1.1 编译原理
JavaScript引擎进行编译的步骤和传统编译语言非常类似,在某些环节可能更复杂
传统编译语言的流程中,程序中的一段源代码在执行之前会经历三个步骤,统称为“编译”
-
分词/词法分析
提示:个人理解
// 比如,var a = 2 会将它分割为"var"、"a"、"="、"2",空格是否会被做成词法单元取决于空格在此是否有意义
// 个人感觉词法分析就是将字符流转化成记号流
var a = 2
//转化为
list= [
{type:'Keyword',value:'var'},
{type:'Identifier',value:'a'},
{type:'Punctuator',value:':'},
{type:'Numberic',value:'2'}
]
- 解析/语法分析
// 换成的抽象语法树
json = {
"type":"Program",
"start":0, // 开始字符标识位置
"end":9, // 结束字符标识位置
"body":[
{
"type":"VariableDeclaratoration",
"start":0, // 开始字符标识位置
"end":9, // 结束字符标识位置
"declarations":[
{
"type":"VariableDeclarator",
"start":4, // 开始字符标识位置
"end":9, // 结束字符标识位置
"id":{
"type":"Identifier",
"start":4, // 开始字符标识位置
"end":5, // 结束字符标识位置
"name":"a",
},
"mit":{
"type":"Literal",
"start":8, // 开始字符标识位置
"end":9, // 结束字符标识位置
"value":"2",
"row":"2",
}
}
],
"kind":"var"
}
],
"sourceType":"module"
}
- 代码生成
代码生成:引擎=>内存=>变量a=>赋值a给变量a
总结:JavaScript引擎会在语法分析和代码生成环节有特定的步骤来对性能进行优化,包括对冗杂元素进行优化等。JavaScript在执行一段代码前都要进行编译,然后做好执行他的准备,通常情况下它会马上执行。
1.2 理解作用域
1.2.1 演员表
- 引擎
从头到尾负责整个JavaScript程序的编译及执行过程 - 编译器
负责语法分析及代码生成 - 作用域
负责收集并维护由所有声明的变量组成的一系列查询,并实施一套严格的规则,确定当前执行代码对这些变量的访问权限
1.2.2 对话
总结:变量赋值
1.2.3 编译器有话说
RHS查询:取到它的源值,简单的说RHS只是引用不涉及到赋值
LHS查询:是进行赋值操作
function foo(a){
console.log(a); // 简单的引用a,RHS查询
}
foo(2) // foo()这个函数是进行引用了具名函数foo所以是RHS查询,但是里面有隐性的LHS查询,因为foo(2)里面的2传给a了所以就有了a=2的LHS查询
总结: (var foo = function() ) 如果进行声明,则不能单纯的理解做了LHS查询赋值,因为引擎不会有线程专门用来讲一个函数值分配给foo
1.2.4 引擎和作用域的对话
function foo(a){
console.log(a) // 2
}
foo( 2 )
总结:
引擎=>foo RHS引用
作用域=>编译器声明了,它是一个函数,给
引擎=>执行foo
引擎=>a进行LHS引用
作用域=>foo的一个形式参数,给
引擎=>把2赋值给a
引擎=>consoleRHS引用
作用域=>console是个内置函数,给
引擎=>找到log()
引擎=>找到a的RHS引用
作用域=>变量没变,给
引擎=>把a的值2传递给log()
1.2.5 小检测
function foo(a){
var b=a;
return a+b
}
var c =foo(2)
总结:
LHS:
c=foo(2) foo(a =2) b=a
RHS:
foo(2) b=a(a) a+b(a和b各一次)
1.3 作用域嵌套
总结:
当发生查询时,作用域的查询是
当前作用域=>上级作用域…=>全局作用域=>停止
1.4 异常
总结:
当RHS查询不到结果,变量没有声明,引擎抛出ReferenceError,ReferenceError是非常重要的异常类型
当LHS查询,在全局也不能找到目标变量,全局作用域就会创建一个具有该名称的变量返回给引擎
(注:非严格模式,严格模式下也抛出ReferenceError)
RHS查询一个非函数类型的值进行函数调用或者引用null或者undefined类型的值中的属性,引擎会抛出TypeError
ReferenceError是作用域判别失败,TypeError是作用域判别成功,操作是非法的
总结
提示:这里对文章进行总结:
作为程序员,我是真觉的JavaScript是一本好书,因为我从中学到了很多,也了解了我之前很多没有关注到的细节,就像一个简单的异常抛出我们每天都在打交道,可我从来没有深究过。