《重学前端》
https://time.geekbang.org/column/article/77345
JavaScript执行(16-19)
宏观与微观任务(tasks & microtasks)
宿主发起的任务称为宏观任务,宏观任务的队列就相当于事件循环
JavaScript引擎发起的任务称为微观任务
Promise永远在队列尾部添加微观任务。setTimeout等宿主API,则会添加宏观任务。这里的顺序问题在各大浏览器表现有些不同
一篇值得阅读的文章
setTimeout & Promise
一个典型的列子
var r = new Promise(function(resolve, reject){ console.log("a"); resolve() }); setTimeout(()=>console.log("d"), 0) r.then(() => console.log("c")); console.log("b")
我们发现,不论代码顺序如何,d必定发生在c之后,因为Promise产生的是JavaScript引擎内部的微任务,而setTimeout是浏览器API,它产生宏任务。
如果一个例子不够说明问题,再来一个
setTimeout(()=>console.log("d"), 0) var r1 = new Promise(function(resolve, reject){ resolve() }); r1.then(() => { var begin = Date.now(); while(Date.now() - begin < 1000); console.log("c1") new Promise(function(resolve, reject){ resolve() }).then(() => console.log("c2")) });
此处的 d 仍然在 c2 后执行
函数的执行
- 闭包其实只是一个绑定了执行环境的函数
- var声明作用域函数执行的作用域。也就是说,var会穿透for 、if等语句
- 没有 let 的年代,使用立即执行的函数表达式
- for; if; switch; try/catch/finally 会产生 let 使用的作用域
两个函数的对比
function showThis(){ console.log(this); } var o = { showThis: showThis } showThis(); // global o.showThis(); // o
class C { showThis() { console.log(this); } } var o = new C(); var showThis = o.showThis; showThis(); // undefined !!!! why ??? o.showThis(); // o
为什么行为不一样?
因为class设计成了默认按strict模式执行,如果把上面的例子中加入
"use strict"
,行为就一致了语句的分类
Completion Record
[[type]]表示完成的类型,有break continue return throw和normal几种类型;
[[value]]表示语句的返回值,如果语句没有,则是empty;控制台返回的就是这个
[[target]]表示语句的目标,通常是一个JavaScript标签
控制型语句
带标签的语句示例:
outer: while(true) { inner: while(true) { break outer; } } console.log("finished")
一个浏览器是如何工作的?(10-14)
把一个URL变成一个屏幕上显示的网页
过程,一条流水线:
- 浏览器首先使用HTTP协议或者HTTPS协议,向服务端请求页面;
- 把请求回来的HTML代码经过解析,构建成DOM树;
- 计算DOM树上的CSS属性;
- 最后根据CSS属性对元素逐个进行渲染,得到内存中的位图;
- 一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度;
- 合成之后,再绘制到界面上。
一个 TCP 工具:telnet