zoukankan      html  css  js  c++  java
  • JavaScript 结构化 Structure

    结构化(一)

    事件循环&宏任务&微任务

    • 事件循环是什么?

      事件循环是浏览器执行任务的机制,它会不断循环判断消息队列中是否有任务,队列中的任务都是指宏任务,而宏任务中包含微任务队列,在宏任务结束前后执行微任务队列,直到微任务队列中为空才结束这个宏任务。

    • 宏任务是什么?

      • 渲染事件(如解析 DOM、计算布局、绘制);
      • 用户交互事件(如鼠标点击、滚动页面、放大缩小等);
      • JavaScript 脚本执行事件;网络请求完成、文件读写完成事件。 为了协调这些任务有条不紊地在主线程上执行,页面进程引入了消息队列和事件循环机制,渲染进程内部会维护多个消息队列,比如延迟执行队列和普通的消息队列。然后主线程采用一个 for 循环,不断地从这些任务队列中取出任务并执行任务。我们把这些消息队列中的任务称为宏任务。
    • 微任务是什么?

      微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前。

      • 微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列。
      • 微任务的执行时长会影响到当前宏任务的时长。比如一个宏任务在执行过程中,产生了 100 个微任务,执行每个微任务的时间是 10 毫秒,那么执行这 100 个微任务的时间就是 1000 毫秒,也可以说这 100 个微任务让宏任务的执行时间延长了 1000 毫秒。所以你在写代码的时候一定要注意控制微任务的执行时长。
      • 在一个宏任务中,分别创建一个用于回调的宏任务和微任务,无论什么情况下,微任务都早于宏任务执行。

    其实所有的JS代码都是一个微任务,只是哪些微任务构成了一个宏任务;执行在JS引擎里的就是微任务,执行在JS引擎之外的就是宏任务,循环宏任务的工作就是事件循环。

    事件循环不属于JavaScript引擎实现的东西,而是由浏览器或node js宿主环境实现的

    script标签、UI交互、setTimeout、setInterval都会创建宏任务

    一个宏任务只存在一个微任务队列,微任务根据入队时间顺序执

    Promise的then方法以及async函数里的await会将一个微任务入队

    宏任务&微任务执行顺序 实验代码

    代码

    async function afoo(){
        console.log("1");
        await new Promise(resolve => resolve());
        console.log("2");
    }
    new Promise(resolve => (console.log("3"), resolve()))
        .then(()=>(
            console.log("4"), 
            new Promise(resolve => resolve())
                .then(() => console.log("5")) ));
    
    setTimeout(function(){
        console.log("6");
        new Promise(resolve => resolve()) .then(console.log("7"));
    }, 0);
    console.log("8");
    console.log("9");
    afoo();
    
    // 3
    // 8
    // 9
    // 1
    // 4
    // 2
    // 5
    // 6
    // 7
    

    解析:

    • 解析:
      • 第一个宏任务:
        • 3
          • 入队 4
        • 8
        • 9
        • 1
          • 入队 2
        • 4
          • 入队 5
        • 2
        • 5
      • 第二个宏任务:
        • 6
          • 入队 7
        • 7

    结构化(二)

    从上到下

    • JS Context => Realm
      • Realm1 Realm2 ... 都会创建一套
        • global
          • Infinity NaN undefined Array Objecy Date ...
    • Macro
    • Micro
    • 函数调用(Execution Context)
    • Statement
    • Expression
    • 直接量/变量/this

    Realm

    对象分类

    • 宿主对象 (Host Objects): JavaScript 宿主环境提供的对象

      • window
        • 一部分来自 js
        • 一部分来自 浏览器
    • 内置对象 (Build-in Objects): JavaScript 语言提供

      • 固有对象 (Intrinsic Objects): 标准规定,随着 JavaScript 运行时创建而自动创建的对象实例

        • js 执行前就创建,类似基础库
      • 原生对象 (Native Objects): 用户通过 Array RegExp 等内置构造器或特殊语法创建

        native-objects

        • 可以 new 创建新的对象
        • 无法通过 class/extend 或 纯 js 代码实现
        • 这些构造器创建的对象使用了 私有字段,无法被原型继承
      • 普通对象 (Ordinary Objects): 由 {} Object 构造器 或 class 创建,能够被原型继承

    对象模拟函数和构造器

    通过 私有字段 模拟

    • 函数对象
      • [[call]]
    • 构造器对象
      • [[construct]]

    实现 [[call]] 和 [[construct]] 行为不一致

    new Date() // object
    Date() // string
    
    new Image() // object
    Image() // error
    

    function 或 Function 构造器创建,[[call]] 和 [[construct]] 行为相似

    function f() {
      return 1
    }
    f() // [[call]]
    new f() // [[constuct]]
    

    [[construct]] 执行过程

    • 以 Object.prototype 创建新对象
    • 以 新对象 为 this,调用 [[call]]
    • [[call]] 返回对象,或 返回 新对象

    获取全部固有对象

    标准中全部对象的定义,规定了以下全局对象的属性。查找这些对象的 属性 和 Getter/Setter,就可以获得所有 固有对象

    • 三个值
      • Infinity
      • NaN
      • undefined
    • 九个函数
      • eval
      • isFinite
      • isNaN
      • parseFloat
      • parseInt
      • decodeURI
      • decodeURIComponent
      • encodeURI
      • encodeURIComponent
    • 一些构造器
      • Array
      • Date
      • RegExp
      • Promise
      • Proxy
      • Map
      • WeakMap
      • Set
      • WeakSet
      • Function
      • Boolean
      • String
      • Number
      • Symbol
      • Object
      • Error
      • EvalError
      • RangeError
      • ReferenceError
      • SyntaxError
      • TypeError
      • URIError
      • ArrayBuffer
      • SharedArrayBuffer
      • DataView
      • Typed Array
      • Float32Array
      • Float64Array
      • Int8Array
      • Int16Array
      • Int32Array
      • UInt8Array
      • UInt16Array
      • UInt32Array
      • UInt8ClampedArray
    • 四个用于当作命名空间的对象
      • Atomics
      • JSON
      • Math
      • Reflect

    函数调用(Execution Context)

    执行栈

      execution context2 // running execution context
      execution context1
      execution context0
    execution context stack
    
    • execution context
      • code evaluation state 代码执行位置
        • async await generator
      • Function
        • context 为函数
        • 全局 script 是 null
      • Script/Module
        • 同上
      • Generator
        • generator 产生的,否则是 null
      • Realm
      • LexicalEnvironment
        • 词法环境,获取变量值时用到的
      • VirableEnvironment

    LexicalEnvironment

    • this
      • 2019 版本,老版在 context
    • new.target
    • super
    • 变量

    VirableEnvironment

    历史包袱,处理 var 声明

    Environment Record

    链表结构

    • Environment Record
      • Declarative Environment Record
        • Function Environment Record
        • Module Environment Record
      • Global Environment Record
      • Object Environment Record
        • with eval

    Function Closure

    Function: foo
      Environment Record
        y:2
      Code
        console.log(y)
    var y = 2
    function foo() {
      console.log(y)
    }
    foo()
    

    嵌套的 Environment

    Function: foo3
      Environment Record ---> Environment Record
        x:3                     y:2
      Code
        console.log(y,x)
    var y = 2
    function foo() {
      var x = 3
      return function foo3() {
        console.log(y, x)
      }
    }
    foo()
    

    箭头函数,附加 this

    Function: foo3
      Environment Record ---> Environment Record
        x:3                     y:2
        this: global
      Code
        console.log(y,x)
    var y = 2
    function foo() {
      var x = 3
      return () => {
        console.log(y, x)
      }
    }
    foo()
    

    Realm

    var o = new Object() // 不需要 realm,当前 realm 的 lex env 中可以获取到
    var o = {} // 需要 realm,比如 别的 iframe 中的 {} 的不是当前的 Object 实例,所以需要确定在哪个 realm
    Object.getPrototypeOf({}) === Object.prototype
    
  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13099263.html
Copyright © 2011-2022 走看看