# 面试复盘(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,异步的神
相关推荐
moyu842 分钟前
前端存储三剑客:Cookie、LocalStorage 与 SessionStorage 全方位解析
前端
不爱说话郭德纲6 分钟前
👩‍💼产品姐一句小优化,让我给上百个列表加上一个动态实时计算高度的方法😿😿
前端·vue.js·性能优化
现在没有牛仔了9 分钟前
小试牛刀,用electron+vue3做了一个文件归纳程序~
前端·electron
FogLetter11 分钟前
Prisma + Next.js 全栈开发初体验:像操作对象一样玩转数据库
前端·后端·next.js
知识分享小能手11 分钟前
React学习教程,从入门到精通, React教程:构建你的第一个 React 应用(1)
前端·javascript·vue.js·学习·react.js·ajax·前端框架
李剑一12 分钟前
别乱封装,你看出事儿了吧...
前端·vue.js
文心快码BaiduComate16 分钟前
新增Zulu-CLI、企业版对话支持自定义模型、一键设置自动执行、复用相同终端,8月新能力速览!
前端·后端·程序员
walking95719 分钟前
JavaScript 神技巧!从 “堆代码” 到 “写优雅代码”,前端人必看
前端·面试
前端西瓜哥24 分钟前
图形编辑器开发:基于矩阵的画布缩放和移动实现
前端
walking95724 分钟前
前端 er 收藏!高性价比 JS 工具库,轻量又强大
前端·面试