《前端面试总结点线面》之点-JavaScript篇

本文是《前端面试总结点线面》系列的一部分,聚焦JavaScript核心知识点,涵盖ES、EventLoop、垃圾回收机制、作用域与闭包、this、节流防抖等内容,旨在帮助前端开发者复习和巩固JavaScript基础知识,提升面试准备。
摘要由CSDN通过智能技术生成

《前端面试总结点线面》系列是为了收拢杂而乱的前端领域知识,由点及线,再涉及面,目的是为帮助广大前端同学复习巩固或查漏补缺或增删改查,为了更好的建立前端领域知识体系,为了更好的为前端面试做好准备,从而做一个合格、进步的前端开发工程师。

JavaScript

ES

  1. ES6
    • let const class module
    • arrow function, 函数参数默认值
    • 模版字符串
    • 赋值解构
    • 剩余操作符
    • promise generator
  2. ES7
    • Array.prototype.includes
    • 指数操作符 **
  3. ES8
    • async/await
    • Object.values/Object.entries
    • String padding
    • Object.getOwnPropertyDescriptors
  4. ES9
    • Promise.finally
    • 异步迭代 for await of
  5. ES10
    • JSON.stringify
    • Array.prototype.flat
    • BigInt

EventLoop

EventLoop 是一个程序结构,用于等待和发送消息和事件。 程序中设置两个线程,一个负责程序本身的运行,叫做主线程;另一个负责主线程与其他线程(主要是 IO 操作)的通信,称为 EventLoop 线程(消息线程)。 主线程开始运行,每当遇到 IO 操作,主线程就让 EventLoop 线程通知相应的 IO 程序,主线程接着往后运行,当 IO 完成之后,EventLoop 线程再把结果返回主线程。主线程调用事先设定的回调函数,完成任务。

任务队列

  1. 所有同步任务都在主线程上运行,形成一个执行栈(execution context stack)
  2. 主线程之外还存在一个任务队列(task queue),只要异步任务有了结果,就在任务队列放置一个事件
  3. 一旦执行栈中所有的同步任务执行完毕,系统就会读取任务队列,进入执行栈。
  4. 主线程不断重复第三步。

Event Loop

主线程在运行的时候,会产生堆(heap)和栈(stack),栈中的代码调用各种外部 API,它们在任务队列中加入各种事件(click,load,done)。只要栈中的代码执行(同步任务)完毕,主线程就会去读取任务队列(异步任务),依次执行那些事件对应的回调函数。

宏任务 macrotask

setTimeout, setInterval, setImmediate, I/O, callabck, UI 渲染, MessageChannel

优先级: 主代码块 > setImmediate > postMessage > setTimeout/Interval

微任务 microtask

process.nextTick,Promise, MutationObserver, Async

优先级: process.nextTick > Promise > MutationObserver

微任务意义:

减少更新时的渲染次数因为根据 HTML 标准,会在宏任务执行结束之后,在下一个宏任务开始执行之前,UI 都会重新渲染。如果在 microtask 中就完成数据更新,当 macro-task 结束就可以得到最新的 UI 了。如果新建一个 macro-task 来做数据更新的话,那么渲染会执行两次

执行顺序

  1. 执行 macrotask 队列的一个任务
  2. 执行当前 microtask 队列的所有任务
  3. UI render
  4. 浏览器只保证 requestAnimationFrame 在重绘之前执行,没有确定的时间,何时重绘由浏览器决定。
  5. requestIdleCallback 在重绘之后执行,并且是否有空执行要看浏览器的调度,如果一定要在某个时间内执行,调用 timeout 参数。

示例 1:

示例 2:

垃圾回收 GC

  • 标记清除法
    • 将不再使用的对象标记为“无法到达的对象”,即从根部(全局对象)开始定时扫描内存中的对象,凡事能从根部到达的对象,保留。那些从根部出发无法触及的对象被标记为不可使用,稍后进行回收。
    • 垃圾收集器在运行的时候给存储在内存中的所有变量添加标记,然后他会去掉环境中的变量和被环境中的变量引用的变量的标记,而在此之后再被添加标记的变量被视为准备删除的变量,原因是环境中的变量已经无法访问这些变量了。最后垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
  • 引用计数法 垃圾收集器跟踪收集每个值被引用的次数。当声明一个变量并将一个引用类型的值赋给该变量时,则这个值的引用次数为 1,如果同一个值又被赋给另一个变量,则值的引用次数加 1。相反,如果包含这个值的变量又取得另一个值,则这个值的引用次数减 1。当这个值的引用次数为 0,就表示没有办法再访问这个值,就可以将其内存空间回收起来,当垃圾回收器下一次运行的时候,就会回收那些引用次数为 0 的值所占用的内存空间。

内存泄漏

  1. 意外的全局变量
    • 使用 use strict 严格模式
  2. 被遗忘的计时器或回调函数
    • clearTimeout / clearInterval / removeEventListener
  3. 脱离 DOM 元素的引用
    • WeakMap / WeakSet 弱引用
  4. 闭包

调用堆栈

执行上下文

  • 全局执行上下文 - 全局对象(this 指向这个对象)
  • 函数执行上下文 - 函数被调用的时候创建
  • EVAL 函数执行上下文 - eval 环境中

执行栈:用于存储在代码执行期间创建的所有上下文,LIFO(后进先出)

执行上下文创建

  1. 确定 this 的值,thisBinding
    • 全局执行上下文,this 指向全局对象,浏览器->window,nodejs -> 文件 module 对象
    • 函数执行上下文,this 的值取决于函数的调用方式(默认、隐式、显示、硬、new 绑定、箭头函数)
  2. 词法环境(Lexical Environment) 创建 - 存储 函数声明和 let、const 绑定
    • 环境记录(EnvironmentRecord):存储函数和变量声明实际位置
      • 全局环境 - 全局变量和全局对象
      • 函数环境 - 包括 arguments 对象
    • 对外部环境的引用(outer):可以访问其外部词法环境
      • 全局 - null
      • 函数 - 全局或引用环境
  3. 变量环境(Variable Environment) 创建 - 仅存储 var 变量绑定
GlobalExectionContext = {

  ThisBinding: <Global Object>,

  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // 标识符绑定在这里
      a: < uninitialized >,
      b: < uninitialized >,
      multiply: < 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值