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
    
  • 相关阅读:
    ajax 函数外调用
    a连接 h5点击有背景阴影
    禁止微信上下滑动
    ios 倒计时 不动 例如 2017-09-06 00:24:35
    6-10位 a-z || A-Z ||0-9 正则
    正则 不能输入中文
    正整数正则 (选择商品数量)
    手机号正则
    input输入框只能输入数字而且开头不能为零
    do...while02
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13099263.html
Copyright © 2011-2022 走看看