JS知识点+试题(一)

作用域的深层次理解

执行期的上下文
-当函数代码执行的前期会创建一个执行期上下文的内部对象AO(作用域)
-这个内部的对象是预编译的时候创建出来的因为当函数被调用的时候会先进行预编译一在全局代码执行的前期会创建一个执行期的上下文的对象GO

#函数作用域预编译

  1. 创建ao对象A0{}
  2. 找形参和变量声明将变量和形参名当做AO对象的属性名值为undefined
  3. 实参形参相统一
  4. 在函数体里面找函数声明值赋予函数体

#全局作用域的预编译

  1. 创建GO对象
  2. 找变量声明将变量名作为GO对象的属性名值是undefined
  3. 找函数声明值赋予函数体
  •  

结果:

 

 

在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:

  • 在此次 tick 中选择最先进入队列的任务(oldest task),如果有则执行(一次)
  • 检查是否存在 Microtasks,如果存在则不停地执行,直至清空 Microtasks Queue
  • 更新 render
  • 主线程重复执行上述步骤

宏任务

(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。

浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个(macro)task执行结束后,在下一个(macro)task 执行开始前,对页面进行重新渲染,流程如下:

(macro)task->渲染->(macro)task->...

宏任务包含:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

微任务

microtask,可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。

所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。

微任务包含:

Promise.then
Object.observe
MutationObserver
process.nextTick(Node.js 环境)

运行机制

在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:

    • 执行一个宏任务(栈中没有就从事件队列中获取)
    • 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
    • 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
    • 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
    • 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)

 

 Promise.resolve()——微任务

 

 

 修改该题

添加

 

 

 

 btn.click() 触发上方 全部代码 宏任务+微任务 (1,2)顺序输出

  •  

 

 

await() 后的代码不再执行 

//宏任务timeout

//微任务async1 end promise2

结果

  •  

     

     

     

     

     

     

     

     

     

 

posted @ 2022-03-20 15:47  Clematis  阅读(48)  评论(0)    收藏  举报