《重学前端》

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变成一个屏幕上显示的网页

过程,一条流水线:

  1. 浏览器首先使用HTTP协议或者HTTPS协议,向服务端请求页面;
  2. 把请求回来的HTML代码经过解析,构建成DOM树;
  3. 计算DOM树上的CSS属性;
  4. 最后根据CSS属性对元素逐个进行渲染,得到内存中的位图;
  5. 一个可选的步骤是对位图进行合成,这会极大地增加后续绘制的速度;
  6. 合成之后,再绘制到界面上。

一个 TCP 工具:telnet

上次更新: 6/5/2020, 3:22:23 AM