JS在浏览器的执行机制/执行上下文/浏览器进程

JS在浏览器的执行机制

  • 主线程和执行栈,所有的任务都会放到执行栈中等待主线程来执行
  • 任务队列:承载任务的队列。Event Loop就是会不断地过来循环访问这个队列,查看是否有任务可以运行
  • 执行过程
    1. 主线程自上而下执行所有代码
    2. 同步任务直接进入到主线程被执行,而异步任务则进入到Event Table并注册相对应的回调函数
    3. 异步任务完成后,Event Table会将这个函数移入任务队列
    4. 主线程任务执行完了以后,会从任务队列中读取任务,进入到主线程去执行
    5. 循环以上
  • 浏览器端事件循环中的异步队列有两种:宏任务队列和微任务队列
  • 宏任务(MacroTask):几乎所有的同步代码都是宏任务,还包括setTimeOut等
  • 微任务(MicroTask):prmise.then(new Promise不是微任务)

JS的执行上下文

分为全局执行上下文函数执行上下文

  • 全局执行上下文:任何不在函数内部的代码都在全局上下文中。浏览器的情况下,它会执行两件事:创建一个全局的 window对象,并且设置this的值等于这个全局对象。一个程序中只会有一个全局执行上下文
  • 函数执行上下文函数被调用时,都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序执行
  • 执行栈后进先出,用来存储代码运行时创建的所有执行上下文
  • 作用域:作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。JavaScript采用词法作用域,也就是静态作用域
  • 词法作用域:函数的作用域在函数定义的时候就决定了
  • 闭包:闭包是一个可以访问外部作用域中变量的内部函数,这些被引用的变量直到闭包被销毁时才会被销毁,可以通过闭包来达到封装性
  • 函数结束时
    • 这个本地执行上下文从执行栈中弹出
    • 函数将返回值返回调用上下文
    • 这个本地执行上下文被销毁,这个本地执行上下文中声明的所有变量都将被删除,不再有变量
  • this指向
    1. new调用:绑定到新创建的对象
    2. call/apply/bind调用:绑定到指定的对象
    3. 上下文对象调用:绑定到上下文对象
    4. 默认:全局对象
    5. 箭头函数根据外层作用域来决定this,继承外层函数调用的this绑定

浏览器进程

  • 浏览器(多进程)包含了主进程第三方插件进程GPU进程(浏览器渲染进程),其中GPU进程(多线程)和Web前端密切相关,包含以下线程
    • GUI渲染线程
    • JS引擎线程
    • 事件触发线程(和Event Loop密切相关)
    • 定时触发器线程
    • 异步HTTP请求线程

      注:GUI渲染线程JS引擎线程是互斥的,为了防止DOM渲染的不一致性,其中一个线程执行时另一个线程会被挂起
  • 任务处理
    • 宏任务是每次执行栈执行的代码
    • 浏览器为了能够使得JS引擎线程GUI渲染线程有序切换,会在当前宏任务结束之后,下一个宏任务执行开始之前,对页面进行重新渲染(宏任务 > 渲染 > 宏任务 > ...
    • 微任务是在当前宏任务执行结束之后立即执行的任务。微任务的响应速度相比setTimeout(下一个宏任务)会更快,因为无需等待UI渲染
    • 当前宏任务执行后,会将在它执行期间产生的所有微任务都执行一遍
    • 宏任务中的事件是由事件触发线程来维护的
    • 微任务中的所有任务是由JS引擎线程维护的
  • 任务处理流程
    1. 执行一个宏任务
    2. 执行过程中如果遇到微任务,就将它添加到微任务的任务队列
    3. 宏任务执行完毕后,立即执行当前微任务队列中的所有任务(依次执行)
    4. JS引擎线程挂起,GUI线程执行渲染
    5. GUI线程渲染完毕后挂起,JS引擎线程执行任务队列中的下一个宏任务

你可能感兴趣的:(JS在浏览器的执行机制/执行上下文/浏览器进程)