You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承Array的自定义类调用splice触发map函数报错问题排查

问题原因分析

这个错误的核心是你自定义的PositionsAndMedia构造函数的参数设计,和Array内置方法调用构造函数的方式不匹配。

你的构造函数预期接收一个数组作为唯一参数,但当你调用splice、slice这类Array内置方法时,这些方法在生成返回的新数组实例时,会调用你的PositionsAndMedia构造函数,并且将新数组的元素作为单独的参数逐个传递,而不是把元素包装成一个数组传递。

举个具体的例子:假设splice删除了1个元素,它会执行new PositionsAndMedia(被删除的那个元素),此时构造函数里的x就是这个单个元素(不是数组),自然调用x.map()就会抛出“不是函数”的错误。

解决方法

有两种实用的解决方案,你可以根据业务需求选择:

方案1:让构造函数兼容可变参数

修改构造函数,使其既能处理用户传入的单个数组参数,也能处理Array方法传入的多个元素参数:

class PositionsAndMedia extends Array {
  constructor(...args) {
    // 统一处理输入:如果是单个数组参数,就用数组内容;否则直接用传入的所有参数
    const inputItems = args.length === 1 && Array.isArray(args[0]) 
      ? args[0] 
      : args;
    // 避免重复创建MyClass实例:如果已经是MyClass实例,直接保留
    super(...inputItems.map(item => item instanceof MyClass ? item : new MyClass(item)));
  }
}

这种方式的好处是,所有Array内置方法返回的仍然是PositionsAndMedia实例,且内部元素保持MyClass类型,完全符合你的自定义类设计。

方案2:指定Array方法返回普通Array

如果你不需要内置方法返回自定义类实例,可以重写类的Symbol.species属性,让Array方法生成普通的Array实例:

class PositionsAndMedia extends Array {
  constructor(x) {
    super(...x.map(item => new MyClass(item)));
  }

  // 告诉Array内置方法:用Array作为构造函数创建返回值
  static get [Symbol.species]() {
    return Array;
  }
}

这样调用splice时,返回的就是普通Array,不会触发你的自定义构造函数,也就不会出现错误。但要注意,这种方式下所有Array方法的返回值都不再是PositionsAndMedia类型,需要根据你的业务场景判断是否适用。

内容的提问来源于stack exchange,提问作者Paolo Benvenuto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:32:58