# 面试复盘(2)--某硬件大厂前端

整个面试过程还是挺舒适的,回答得还可以,就记录一下几个回答得不是很好的问题吧:

vue2的批量更新

即缓存数据的变更(如果有相同的更新要做合并操作),异步进行视图的更新(通过vue.nextTick()实现)。

缓存数据变更

ini 复制代码
let queue = []; // 使用数组缓存变更的 watcher
let has = {}; // watcher id的收集,用于查重
let pending = false; // 标志位
​
function collectQueueWatcher(watcher) {
    let id = watcher.id;
    if (has[id] == null) {
        has[id] = true;
        queue.push(watcher);
        if (!pending) {
            nextTick(flushschedulerQueue); // 异步任务,在它执行前,同步代码可以往 缓存队列queue 中继续添加watcher
            pending = true;
        }
    }
}
function flushSchedulerQueue() {
    queue.forEach(watcher => watcher.update());
    queue = [];
    has = {};
    pending = false;
}

异步更新

任何异步操作都是基于js的事件循环机制的,即在同步代码执行的过程中把任务入栈到 微任务队列 或者 宏任务队列。在这里我们使用Promise来创建微任务,实现异步操作。

javascript 复制代码
// nextTick的简单实现,使用Promise
function nextTick (fn) {
    return Promise.resolve().then(fn);
}

nextTick优化

上面的这个nextTick的简单实现对于视图更新来说已经够用了,毕竟视图更新本身就已经有缓存队列来实现批量操作,那么如果是用户手动调用nextTick呢?按照这个简单实现,我们得创造许多个微任务。所以,我们可以在这里也使用一个缓存队列来减少微任务的创建,优化丐版nextTick

ini 复制代码
let nextQueue = [];
let pending = false;
​
function nextTick (fn) {
    fnQueue.push(fn);
    if (!pending) {
        Promise.resolve().then(flushNextQueue);
        pending = true;
    }
}
​
function flushNextQueue() {
    nextQueue.forEach(fn => fn());
    nextQueue = [];
    pending = false;
}

PS: 这里使用forEach还是很关键的,它能记住开始执行时的array的状态,即使循环过程中这个array有新增也不会造成影响。

对比vue2diff,vue3的优化

大概看了一些详细文章,vue3中新增了静态优化比较,即对于被标记的静态节点直接拿来复用。

【后续再深入看下代码来补充这一part】

Map和Set

Map

Map相当于是普通键值对象的改良

  • 普通对象中,键名会转化为string类型,Map允许任何类型的键值
  • 提供查询时O(1)复杂度的优化

使用

go 复制代码
const map = new Map(); // 创建Map类型的数据
map.set('name', '王五');
map.get('name'); // 取值
map.has('name'); // 查询
map.delete('name'); // 删除
map.clear(); // 清空所有键值对
map.size(); // 返回键值对的数量

查询需求比较频繁的时候用它(相当于 用空间换时间)。

Set

集合,Set相当于数组的改良

  • Set中的元素是唯一的,不重复
  • 增删查都很快O(1)
  • 不能通过索引来访问
  • 常用forEach或者for..of来遍历

使用

csharp 复制代码
const set = new Set(array);
set.add(1); // 添加元素
set.has(1); // 是否有该元素
set.delete(1); // 删除元素
set.clear(); // 清空元素
set.size(); // 元素数量

一般用于数组去重

WeakMap和WeakSet

WeakMap和Map、WeakSet和Set之间的区别都在于弱引用和强引用,Weak前缀的都是弱引用。

  • WeakMap的键值是弱引用,即垃圾回收不会因为WeakMap的关系而不对无效键值进行回收处理
  • WeakSet中的元素只能是ObjectSymbol类型
  • WeakSet可以实现自动清理回收,实际上也是弱引用的关系,垃圾回收不会因为WeakMap的关系而不对元素进行回收处理

ES6+新特性

这个内容可以讲很多,所以这里列举一些常用的:

  1. letconst,块级作用域,避免了var的变量提升带来的各种麻烦
  2. 箭头函数() => {},相比于function函数最重要的变化是this取决于声明时而不是运行时
  3. 模板字符串,拼接字符很爽
  4. 解构赋值,const {name, age} = user
  5. async/await
  6. 展开预算符...
  7. Proxy,vue3响应式改进的核心,比object.definProperty好使
  8. Promise,异步的神
相关推荐
llz_1122 小时前
web-第二次课后作业
前端·后端·web
vipbic7 小时前
别再把“做个H5”挂嘴边了:这个词,官方压根就没有定义过
前端
AI人工智能+电脑小能手7 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
ZC跨境爬虫8 小时前
跟着 MDN 学CSS day_39:(Flexbox 弹性盒子核心机制)
前端·css·ui·html·tensorflow
小陈同学呦8 小时前
前端如何处理订单状态导航的数据竞态问题
前端·javascript
喵个咪9 小时前
GoWind Toolkit 前端代码生成|Vue3(ElementPlus/Vben)、React(AntDesign)全自动一键生成教程
前端·vue.js·react.js
Cosolar9 小时前
从零写一个 Attention Is All You Need
人工智能·面试·架构
摆烂大大王10 小时前
玩转 OpenClaw:用 TaskFlow + Heartbeat 打造自动化工作流
前端·人工智能·自动化
zhangxingchao10 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
梦想的颜色10 小时前
TypeScript 完全指南(上):从零开始掌握类型系统
前端·typescript