三年JavaScript开发解读"作用域"底层原理

388 阅读3分钟

       三年JS开发经验可能还未达到一个中级工程师得水平,在前端这一块vue、react和其他框架用的也不算很多,可能仅仅是一个框架得奴隶还不算是玩家。我记得刚入职得时候一位老师告诉我:"无论什么框架你要你原生JavaScript基础够硬,也就是3天的学习成本,会用仅仅是开始,有时间看看源码。"

      后来得知这位老师曾是服役国家军事网络安全,主攻项目是网络安全,由于老师赏识前前后后担任了几个项目负责人,跟着老师学到了很多(这里指数据加密)。

顾名思义什么是作用域呢?

作用域就是:在这地谁管事

这类似于我国现有的行政体制,省、市、县、城乡、村;各司其职,在村里服从村长、在省里服从省委,这是一个道理。

JavaScript编译原理

首先声明一下:JavaScript并不是标记语言、动态语言、解释语言、脚本语言,它是——"编译语言"。

什么是编译:

在传统的编译语言的过程中,程序执行的以下三个步骤就是编译

  • Tokenizing   词法分析
  • Parsing          语法分析
  • Product code  代码生成

(1)词法分析:

如果词法生成器在判断单元词法时,调用的是有状态的解析规则,这个过程就是词法分析。

例如:

//我们在代码中写到这样一句
var a = 2;

//上面一行会被分解成 var、 a、= 和 2,而var 、a 、 = 、2就是每一个词法单元
//用var定义变量你是天天在用,但是"词法单元"这个词对你来说应该还陌生
//哪有人会问中间的空格呢?空格是否会被分解成词法单元取决于空格在这门语言中是否具备意义。

(2)语法分析:

程序在经历词法分析之后,想必下一步就是语法分析了。语法分析是将"词法单元流"转换成一个由元素逐级嵌套组成的"抽象语法树"(AST)。AST有一个顶级节点和三个子节点,感性趣的可以再深度查下资料,不做过多的解读了。

(3)代码生成:

"将抽象语法树"转换成可以执行的代码 -的- 过程(注意分句),称之为代码生成。

当你理解了这句话,其实,你就会明白我们日常的工作并非是写代码 ,而是写一些单元词,试图让生成器帮你转换成可以执行的-代码-的过程。

当我们写的作为代码经过词法分析、语法分析、代码生成之后,我们聊一聊浏览器引擎、编译器和作用域

  • 引擎:负责JavaScript程序的全过程的编译和执行
  • 编译器:负责词法分析、语法分析、代码生成这个过程
  • 作用域:收集并维护所有的声明标识符组成的一系列查询,并制定一套所执行的代码对声明的标识符访问权限的规则。

例如:

var a = 2;

这段代码编译器会如何进行编译呢?

(1)编译器首先查询当前作用域是已经存在同变量名?

  • 如果有->忽略->继续编译;
  • 如果没有->要求当前作用域创建一个新的变量,并命名为a;

(2)为引擎生成运行时所需要的代码

  • 引擎运行时首先询问当前作用域,是否存在变量a;
  • 如果存在,引擎将使用该变量;如果该作用域不存在将继续向上查询,直到查询到变量a,并赋值,如果一直查询不到将会抛出undefined;