Array[Symbol.species]

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流浏览器均已支持。

Array[Symbol.species] 静态访问器属性返回用于构造数组方法返回值的构造函数。

警告:[Symbol.species] 的存在允许执行任意代码,并可能产生安全漏洞。它还使得某些优化变得更加困难。引擎实现者正在研究是否移除此功能。如果可能,请避免依赖它。现代数组方法,例如 toReversed(),不使用 [Symbol.species],而是始终返回一个新的 Array 基类实例。

语法

js
Array[Symbol.species]

返回值

调用 get [Symbol.species] 时的构造函数 (this) 的值。返回值用于构造创建新数组的数组方法的返回值。

描述

[Symbol.species] 访问器属性返回 Array 对象的默认构造函数。子类构造函数可以重写它以更改构造函数分配。默认实现基本上是

js
// Hypothetical underlying implementation for illustration
class Array {
  static get [Symbol.species]() {
    return this;
  }
}

由于这种多态实现,派生子类的 [Symbol.species] 默认情况下也将返回构造函数本身。

js
class SubArray extends Array {}
SubArray[Symbol.species] === SubArray; // true

调用那些不修改现有数组但返回新数组实例的数组方法时(例如,filter()map()),将访问数组的 constructor[Symbol.species]。返回的构造函数将用于构造数组方法的返回值。这使得在技术上可能使数组方法返回与数组无关的对象。

js
class NotAnArray {
  constructor(length) {
    this.length = length;
  }
}

const arr = [0, 1, 2];
arr.constructor = { [Symbol.species]: NotAnArray };
arr.map((i) => i); // NotAnArray { '0': 0, '1': 1, '2': 2, length: 3 }
arr.filter((i) => i); // NotAnArray { '0': 1, '1': 2, length: 0 }
arr.concat([1, 2]); // NotAnArray { '0': 0, '1': 1, '2': 2, '3': 1, '4': 2, length: 5 }

示例

普通对象中的 species

[Symbol.species] 属性返回默认构造函数,即 ArrayArray 构造函数。

js
Array[Symbol.species]; // [Function: Array]

派生对象中的 species

在自定义 Array 子类(例如 MyArray)的实例中,MyArray 的 species 是 MyArray 构造函数。但是,您可能希望重写它,以便在派生类方法中返回父 Array 对象。

js
class MyArray extends Array {
  // Overwrite MyArray species to the parent Array constructor
  static get [Symbol.species]() {
    return Array;
  }
}

规范

规范
ECMAScript® 2026 语言规范
# sec-get-array-%symbol.species%

浏览器兼容性

另见