赞
踩
本篇文章给大家谈谈javascript常见编译器,以及javascript 编译原理,希望对各位有所帮助,不要忘了收藏本站喔。
JavaScript是单线程语言,即在浏览器中一个页面只有一个线程在执行js代码。
假设我们有一家工厂(进程),那么 工厂所拥有的独立资源就相当于系统给我们分配的内存(这是独立的)快码论文。
如果我们有多个工厂,每个工厂做不一样的事情,那么也就意味着工厂间是互相独立的,也就是说 进程间互相独立。
工厂里有一个或多个工人(线程),那么: 一个进程包含了一个或多个线程。
多个工人在一个工厂里工作,享受的是这个工厂拥有的独立资源,也就是说: 同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)
工人们之间互相协作完成工厂布置的任务,也就说明: 多个线程在进程中协作完成任务的特点。
总结:
H5新增:
可以理解为是 浏览器 申请开辟的一个新线程来帮助JS引擎完成复杂的计算来减少由于JS执行时间过长而导致的阻塞时长
注⚠️: 需要注意这并不影响JS引擎是单线程的。
解析器:负责将js代码转换为AST抽象语法树
解释器:负责将AST抽转换为字节码,并收集编译器需要的优化编译信息
编译器:利用解释器收集到的信息,将字节码转换为优化的机器码
JavaScript通过 词法分析 和 语法分析 得到语法树后,js引擎开始执行代码,但是JS引擎并不是逐条解释java代码,而是通过一个个标签分隔开的代码段进行的解释执行。
简单来说,它就是能够将 JavaScript代码处理并执行的运行环境,不同的浏览器有不同的JS引擎,而我们常接触的V8正是采用C++编写在Chrome浏览器中被使用的解析引擎。
JS引擎执行过程分成三个阶段:
- 1. 语法分析
- 2. “预编译”阶段(解释阶段)
- 3. 执行阶段
浏览器首先按顺序加载由<></>
标签分割的代码块,加载代码块完毕后,立刻进入以上三个阶段。然后再按顺序查找下一个代码块,再继续执行以上三个阶段,无论是外部脚本文件(不异步加载 即会停止加载后面的内容,停下来解析脚本并对页面进行渲染)还是内部脚本代码块,都是一样的原理,并且都在同一个全局作用域中。
在js代码加载完毕以后,就会进入到语法分析阶段,在这个阶段中js将会检查代码块的语法是否正确。
若有错误语法则直接抛出错误,并停止接下来的执行,而后继续向后查找并加载下一个代码块。
若语法都没有问题,那么就进入接下来的预编译阶段。
在理解这个阶段之前,我们需要优先了解一下js的几种运行环境:
每进入一个不同的运行环境都会创建一个相应的执行上下文(Execution Context),
在一段JS程序中我们会创建很多的执行上下文,而这些执行上下文在JS引擎中会 以栈的方式 执行处理
而这时候形成的栈我们叫它 函数调用栈(Call Stack) ,其中调用栈的 栈底 永远是我们的 全局执行上下文(Global Execution Context) , 栈顶 则永远是 当前的执行上下文 。
我们从一个简单的例子出发:
- function bar() {
- var B_context = "Bar EC";
- function foo() {
- var f_context = "foo EC";
- }
- foo()
- }
- bar()
- 1.创建变量对象(Variable Object)
- 2.建立作用域链(Scope Chain)
- 3.确定this的指向
创建变量对象(Variable Object)
注:在全局环境中,window对象就是全局执行上下文的变量对象,所有的变量和函数都是window对象的属性方法。
例如:
- function fun(a, b) {
- var num = 1;
- function test() {
- console.log(num)
- }
- }
- fun(2, 3)
当执行fun函数并传入参数2和3时:(暂时不讲解作用域链以及this指向)
- funEC = { //fun的执行上下文
- VO: { //变量对象
- arguments: { //arguments对象
- a: undefined,
- b: undefined,
- length: 2
- },
- test: <test reference>, //test函数,在堆内存中地址的引用
- num: undefined //num变量
- },
- scopeChain:[], //作用域链
- this: window //this指向
- }
解析:
创建变量对象是发生在“预编译”阶段,还并没有进入执行阶段,因此这里的变量对象是不可访问的,此时值还是undefined
当我们进入执行阶段开始对其变量属性赋值,变量对象转变为活动对象,此时才可以进行访问,而这个过程就是VO->AO的过程,其中AO就是Active Object活动对象。
注:函数声明提前和变量声明提升是在创建变量对象中进行的,且 函数声明优先级高于变量声明
通过例子来说明:
- var a = 1;
- function b() {
- a = 10;
- return;
- function a() {}
- }
- b();
- console.log(a);
- function foo(){
- function bar() {
- return 3;
- }
- return bar();
- function bar() {
- return 8;
- }
- }
- alert(foo());
- alert(foo());
- function foo() {
- var bar = function() {
- return 3;
- };
- return bar();
- var bar = function() {
- return 8;
- };
- }
解析:输出: 3,优先声明函数foo,因此可以alert出foo函数,此时再foo函数内,先声明变量bar其次,给bar赋值返回值为3的匿名函数,此时执行return语句直接执行输出3,在return后的赋值语句不会再执行
注:不同的运行环境执行都会进入 代码预编译 和 执行 两个阶段,而语法分析则 在代码块加载完毕时 统一检验语法
2 建立作用域链(Scope Chain)
作用域链由当前执行环境的变量对象(也就是未进入执行阶段前)与**上层环境的一系列活动对象(AO)**组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
JS引擎在解释过程中,是严格按照作用域机制来执行的, JS的变量及函数 在定义时 就已经决定了它们的作用域范围,
所以解释JS只要通过静态分析就可以确认每个变量,函数的作用域,因此这些作用域也叫作 静态作用域。
那么举个具体的例子:
- var num = 30;
- function test() {
- var a = 10;
- function innerTest() {
- var b = 20;
- return a + b
- }
- innerTest()
- }
- test()
此时:
- innerTestEC = {
- VO: { b: undefined }, //变量对象
- scopeChain: [VO(innerTest), AO(test), AO(global)], //作用域链:注意顺序,链头是当前作用域,链尾一定是全局作用域
- this: window //this指向
- }
3 确定this的指向:
在全局执行上下文中,this是始终指向全局对象的。
而在执行函数的过程中,就需要考虑函数的调用方式,而函数共有4中调用方式:
- 1. 当它被作为对象的方法调用时,函数的指向为该对象
- 2. 当它直接作为函数被调用时,this通常指向的就是全局对象
- 3. 当它被以构造函数的方式调用时,会将新建的对象作为该函数的this值
- 4. 当它被间接调用也就是被call/bind/apply这样的函数绑定时,this值就是他们要绑定的那个对象。
事件循环机制 可以 完成异步操作,事件循环的执行机制,这里涉及到的概念包括:
我们先来了解一下以下几个线程:
JS引擎线程:
事件触发线程:
定时触发器线程:
异步http请求线程:
注:永远只有JS引擎线程在执行JS脚本程序,以上提及的三个线程只负责将满足触发条件的处理函数推进回调队列中,等待JS引擎线程执行。
事件循环图解如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
Event Loop只做一件事情,那就是负责监听Call Stack和Callback Queue。
当Call Stack里面的内容运行完变成空了, Event Loop就把Callback Queue里面的第一条事件(回调函数)放到调用栈中并执行它,后续不断循环执行这个操作。
⚠️:异步任务又分为:宏任务和微任务(优先级:微>宏)
js执行过程:词法分析 -> 预编译 -> 执行
预编译:js引擎会首先把整个文件进行预处理,以消除一些歧义,这个预处理的过程就叫做预编译
全局预编译:
函数预编译:
undefined
;Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。