面试八股文-JavaScript(第四天)

1.JavaScript 中如何取消请求

使用 AbortController 和 AbortSignal 可以取消 fetch 请求:

javascript 复制代码
const controller = new AbortController();
const signal = controller.signal;

fetch('url', { signal })
  .then(response => response.json())
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('请求已取消');
    }
  });

// 取消请求
controller.abort();

对于 XMLHttpRequest,调用 xhr.abort() 即可取消请求。


2.ES6-ES12 的了解

ES6(2015):

  • let/const、箭头函数、模板字符串
  • 解构赋值、默认参数、Promise
  • class、模块化(import/export)

ES7(2016):

  • Array.prototype.includes
  • 指数运算符 **

ES8(2017):

  • async/await
  • Object.values()/Object.entries()

ES9(2018):

  • Promise.finally
  • 正则表达式改进(命名捕获组)

ES10(2019):

  • Array.flat()/Array.flatMap()
  • Object.fromEntries()

ES11(2020):

  • 可选链操作符 ?.
  • 空值合并运算符 ??

ES12(2021):

  • String.prototype.replaceAll
  • Promise.any

3.用 JS 实现二叉树的定义和基本操作

javascript 复制代码
class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = this.right = null;
  }
}

class BinaryTree {
  constructor() {
    this.root = null;
  }

  insert(val) {
    const newNode = new TreeNode(val);
    if (!this.root) {
      this.root = newNode;
      return;
    }
    let queue = [this.root];
    while (queue.length) {
      let node = queue.shift();
      if (!node.left) {
        node.left = newNode;
        return;
      }
      if (!node.right) {
        node.right = newNode;
        return;
      }
      queue.push(node.left, node.right);
    }
  }

  // 遍历方法(前序、中序、后序略)
}

4.前端跨页面通信的方法

  1. localStorage 事件监听 :

    javascript 复制代码
    window.addEventListener('storage', (e) => {
      console.log(e.key, e.newValue);
    });
  2. BroadcastChannel :

    javascript 复制代码
    const channel = new BroadcastChannel('channel');
    channel.postMessage('data');
  3. window.postMessage :通过 iframe 或新窗口传递消息。

  4. SharedWorker:共享 Worker 实现多页面通信。


map 和 forEach 的区别

  • map 返回新数组,不改变原数组;forEach 无返回值。
  • map 适合链式调用(如 .map().filter()),forEach 仅用于遍历。

5.把 arguments 转成数组

  1. Array.from :

    javascript 复制代码
    const args = Array.from(arguments);
  2. 扩展运算符 :

    javascript 复制代码
    const args = [...arguments];
  3. Array.prototype.slice :

    javascript 复制代码
    const args = Array.prototype.slice.call(arguments);

6.虚拟 DOM 渲染到页面的处理

  1. Diff 算法:比较新旧虚拟 DOM 树的差异。
  2. Patch 阶段:将差异应用到真实 DOM。
  3. 批量更新:合并多次 DOM 操作以提高性能。

7.async/await、generator、promise 的关联和区别

  • Promise :处理异步操作的容器,支持链式调用(.then)。
  • Generator :通过 yield 暂停函数执行,需手动调用 next()。
  • async/await :基于 Promise 和 Generator 的语法糖,使异步代码更像同步。

8.AST 语法树

抽象语法树(Abstract Syntax Tree)是源代码的树状结构表示,用于代码分析、转换(如 Babel)和执行。


9.让 Proxy 监听基本数据类型

通过包装对象实现:

javascript 复制代码
const proxy = new Proxy(new Number(1), {
  get(target, prop) {
    console.log(`访问属性 ${prop}`);
    return Reflect.get(target, prop);
  }
});

10.空数组调用 reduce 的结果

抛出错误:TypeError: Reduce of empty array with no initial value。需提供初始值:

javascript 复制代码
[].reduce((acc, val) => acc + val, 0); // 返回 0

11.reduce 的用途

  1. 求和/乘积 :

    javascript 复制代码
    [1, 2, 3].reduce((acc, val) => acc + val, 0);
  2. 数组转对象 :

    javascript 复制代码
    ['a', 'b'].reduce((acc, val) => ({ ...acc, [val]: val }), {});
  3. 扁平化数组 :

    javascript 复制代码
    [[1], [2]].reduce((acc, val) => acc.concat(val), []);

12.改变 this 指向的方法

  1. call/apply :立即调用函数并指定 this。

    javascript 复制代码
    func.call(context, arg1, arg2);
    func.apply(context, [arg1, arg2]);
  2. bind :返回绑定 this 的新函数。

    javascript 复制代码
    const boundFunc = func.bind(context);
  3. 箭头函数 :继承外层 this。


13.addEventListener 第三个参数

  • 布尔值 :true 表示捕获阶段触发,false(默认)为冒泡阶段。

  • 对象配置 :

    javascript 复制代码
    { capture: true, once: true, passive: true }

14.空值合并运算符 ?? 的使用场景

  1. 默认值 :

    javascript 复制代码
    const value = input ?? 'default';
  2. 避免 0 或 '' 被忽略 (与 || 不同):

    javascript 复制代码
    const count = 0 ?? 42; // 返回 0

15.this 指向混乱的原因

  1. 函数调用方式 :
    • 直接调用时 this 指向全局(严格模式为 undefined)。
    • 方法调用时指向调用对象。
  2. 回调函数 :setTimeout 等异步回调可能丢失 this。

立即过期,浏览器会删除该 cookie。


16.JavaScript 数组的常用方法

  • 修改数组:push、pop、splice、sort
  • 遍历:map、filter、reduce
  • 查询:find、includes、indexOf

17.前端页面截图实现

  1. html2canvas 库 :

    javascript 复制代码
    html2canvas(document.body).then(canvas => {
      document.body.appendChild(canvas);
    });
  2. 浏览器 API :window.print() 或 Chrome 的 captureVisibleTab。


18.canvas 和 webgl 的区别

  • canvas:2D 绘图 API,基于像素操作。
  • webgl:基于 OpenGL 的 3D 图形库,支持硬件加速。

19.实现类似"谷歌图片"系统的考虑

  1. 图片处理 :
    • 压缩与格式转换(WebP)。
    • 缩略图生成。
  2. 搜索功能 :
    • 基于元数据(标签、颜色)或 AI 识别。
  3. 性能优化 :
    • 懒加载、CDN 分发。
  4. 用户体验 :
    • 无限滚动、响应式布局。
相关推荐
“AI国潮设计-小江”27 分钟前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc
lhbweilai1 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
努力努力再努力wz1 小时前
【C++高阶系列】C++20 协程底层原理:函数为什么能暂停?从状态机到 Task,彻底串起挂起、恢复与协程调度
开发语言·c++·c++20·1024程序员节
inksci1 小时前
在线编辑表格,功能强大,json互转
前端·javascript·html
咩咩啃树皮1 小时前
JavaScript 中 this 指向为什么总在变?
开发语言·前端·javascript
程序员清风1 小时前
算法题中的边界条件、测试与调试
开发语言·算法·kotlin
砚底藏山河1 小时前
python量化实操:冷热分层存储
java·开发语言·python·金融
十五年专注C++开发2 小时前
pybind11:一个跨C++和Python平台的编程库
开发语言·c++·python·pybind11
CodeYp20192 小时前
第11讲:stack 和 queue
开发语言·c++·queue·stack
咩咩啃树皮2 小时前
JavaScript 异步流程为什么容易失控?从回调到可维护设计
开发语言·javascript·ecmascript