[{"createTime":1735734952000,"id":1,"img":"hwy_ms_500_252.jpeg","link":"https://activity.huaweicloud.com/cps.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905","name":"华为云秒杀","status":9,"txt":"华为云38元秒杀","type":1,"updateTime":1735747411000,"userId":3},{"createTime":1736173885000,"id":2,"img":"txy_480_300.png","link":"https://cloud.tencent.com/act/cps/redirect?redirect=1077&cps_key=edb15096bfff75effaaa8c8bb66138bd&from=console","name":"腾讯云秒杀","status":9,"txt":"腾讯云限量秒杀","type":1,"updateTime":1736173885000,"userId":3},{"createTime":1736177492000,"id":3,"img":"aly_251_140.png","link":"https://www.aliyun.com/minisite/goods?userCode=pwp8kmv3","memo":"","name":"阿里云","status":9,"txt":"阿里云2折起","type":1,"updateTime":1736177492000,"userId":3},{"createTime":1735660800000,"id":4,"img":"vultr_560_300.png","link":"https://www.vultr.com/?ref=9603742-8H","name":"Vultr","status":9,"txt":"Vultr送$100","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":5,"img":"jdy_663_320.jpg","link":"https://3.cn/2ay1-e5t","name":"京东云","status":9,"txt":"京东云特惠专区","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":6,"img":"new_ads.png","link":"https://www.iodraw.com/ads","name":"发布广告","status":9,"txt":"发布广告","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":7,"img":"yun_910_50.png","link":"https://activity.huaweicloud.com/discount_area_v5/index.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=aXhpYW95YW5nOA===&utm_medium=cps&utm_campaign=201905","name":"底部","status":9,"txt":"高性能云服务器2折起","type":2,"updateTime":1735660800000,"userId":3}]
1.编译原理
传统的编译语言的流程中,程序的一段源代码在执行之前会经历三个步骤:
* 分词/词法分析(Tokenizing/Lexing)
将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元。
* 解析/语法分析
将词法单元流转换成一个由元素逐级嵌套所组成代表了程序语法结构的树(抽象语法树)
* 代码生成
将抽象语法树转换为可执行的过程。
2.理解作用域
1.参与处理代码的部件:
* 引擎:从头到尾负责程序的额编译及执行过程
* 编译器:负责语法分析及代码生成
* 作用域:负责收集并维护所有声明的标识符组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
2.变量的赋值操作执行两个动作:
* 编译器在当前作用域声明一个变量
* 然后在运行时引擎会在作用域中查找该变量。如果能够找到就给对它赋值
3.LHS查询和RHS查询
变量出现在赋值操作的左侧进行LHS查询:试图找到变量的容器本身,从而可以对其赋值(即赋值操作的目标是谁)
变量出现在赋值操作的右侧进行RHS查询:简单地查找某个变量的值(即谁是赋值操作的源头)
(注意:参数传递实际为一种隐式的赋值操作)
3.作用域嵌套
当一个块或函数嵌套在另一个块或函数中,就发生了作用域的嵌套。
因此,在当前作用域中找不到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量或抵达最外层的作用域为止。
LHS和RHS引用都会在当前楼层进行查找,如果没有找到,就会坐电梯上前往上一层楼。如果还是没有找到,以此类推。一旦抵达顶层,可能找到了也可能没找到,无论如何查找过程都将会停止。
4.异常
1.在变量尚未声明时,LHS和RHS查询的行为是不一样的。
* 如果RHS查询在所有嵌套的作用域都遍寻不到所需的变量,引擎将会抛出ReferenceError异常
* 如果LHS查询在全局作用域也无法找到目标变量,全局作用域就会创建一个具有该名称的变量,将其归还给引擎。(前提:程序运行在非严格模式)
* 如果RHS查询到了一个变量,但是尝试对这个变量的值进行不合理的操作,引擎就会抛出一种类型的异常,叫做TypeError。
2.区分ReferenceError和TypeError
* ReferenceError:同作用域判别失败有关
* TypeError:表示作用域判别成功了,对是对结果的操作是非法或不合理的。
3.关于严格模式
严格模式一个不同的行为是:禁止自动或隐式地创建全局变量。