面试八股文-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. 用户体验 :
    • 无限滚动、响应式布局。
相关推荐
凤城老人35 分钟前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)38 分钟前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
sunshine22 girl1 小时前
Java学习六 Java常见API-2--String-3-字符串的截取替换和其他方法
java·开发语言·学习
LOVE️YOU1 小时前
Python 函数名、函数对象与“把函数作为参数传递”
开发语言·python
码艺-Alimjan1 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
sunshine22 girl2 小时前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习
可乐鸡翅yeah_2 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
潼心1412o2 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
夜晚回家3 小时前
Python 零基础入门 | 输入的数字为什么不能直接算
开发语言·python
时间的拾荒人3 小时前
Qt 事件机制全解析:从事件处理到事件过滤器
开发语言·qt·面试