《你不知道的JavaScript》-- 精读(一)

470 阅读3分钟

知识点

1.编译原理

程序中的一段源代码在执行之前会经历三个步骤:分词/词法分析,解析/语法分析,代码生成,统称为“编译”。

简单说,就是有某种方法可以将var a = 2;的AST转化为一组机器指令,用来创建一个叫做a的变量(包括分配内存等),并将一个值储存在a中。

2.理解作用域

  • 引擎:从头到尾负责整个JavaScript程序的编译及执行过程
  • 编译器:负责语法分析及代码生成等
  • 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。

总结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。

3.LHS和RHS

引擎在作用域协助下的查询变量操作

查找并取值是RHS

console.log(a)

查找并赋值是LHS

a = 2;

4.小测验

function foo(a){  // a = 2
    var b = a;   // b =  , = a
    return a + b;  // a   ,b  
}
var c = foo(2)  // c = ...  , foo(2)
// LHS 3处
// RHS 4处

作用域嵌套

function foo(a){
    console.log(a+b);
}
var b = 2;
foo(2) // 4

引擎从当前的执行作用域开始查找变量,如果找不到,就向上一级继续查找。当抵达最外层全局作用域时,无论找到还是没找到,查找过程都会停止。

总结

1.作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,那么就会使用LHS查询,如果目的是获取变量的值,就会使用RHS查询。

2.JavaScript引擎首先会在代码执行前对其进行编译,在这个过程中,像var a = 2这样的声明会被分解成两个独立的步骤:

  • var a 在其作用域中声明新变量
  • a = 2会查询(LHS查询)变量a并对其赋值。

3.不成功的RHS引用会导致抛出ReferenceError异常。不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)

思考

JavaScript引擎是如何区分var a; a的变量类型的?

扩展

编程语言通常会分为汇编语言,机器语言,脚本语言,高级语言四类。而高级语言又会分为解释类语言和编译类语言,通常会将JavaScript归类为解释类语言,但是事实上,它是一门编译类语言,只是与传统的编译语言不同,它会在程序运行前的几微秒内进行编译,并且不会生成字节码文件。

JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。 市面上主要的JavaScript引擎有Chrome浏览器的V8引擎,Mozilla Firefox的Gecko排版引擎,SpiderMonkey和Rhino,以及Opera等。

巴拉巴拉

晚上睡不好的危害:

1.第二天会懵逼,脑子不够用,

2.第二天会暴饮暴食

3.第二天会情绪不在线,易怒

4.最恐怖的是平常可以消化或者没消化完的情绪会反噬,说话会没思考,后悔的次数也变多,会更纠结

解决方法:

1.早睡

2.失眠尝试简单的催眠方法,减轻睡不着的心理负担

3.很多时候,不去担心第二天的事情都不会失眠的,所以在发生晚上睡不好的第二天,也没什么,相信自己的自我调节能力,时刻保持不失控的状态。