最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何识别 Symbol.species 控制派生对象如子类数组的构造函数
时间:2026-06-06 10:14:48 编辑:袖梨 来源:一聚教程网
Symbol.species是否起效,关键看子类实例调用map等内置方法后返回值的constructor是否为期望构造器;它只影响返回新对象的方法(如map、filter、then),不改变继承或new行为,须通过static get [Symbol.species]()定义。
识别 Symbol.species 是否在起作用,关键看“子类实例调用内置方法后,返回值的构造器是不是你期望的那个”。它不改变类继承关系,也不影响你手动 new,只悄悄干预 map、filter、slice、then 这类会返回新对象的内置方法。
看返回值的 constructor 是谁
最直接的方式:调用方法后检查返回值的 constructor 和 instanceof 结果。
-
arr.map(x => x)返回的对象,arr.constructor === Array?还是=== MyArray? -
result instanceof MyArray是true还是false? - 如果
result.constructor指向父类(如Array),且instanceof MyArray为false,说明Symbol.species起效了(且返回的是父类)。
检查子类是否定义了静态 getter
Symbol.species 必须通过静态访问器属性定义,不能写在实例上,也不能用箭头函数。
- 正确写法:
static get [Symbol.species]() { return this; }或return Array; - 错误写法:
[Symbol.species]: () => Array(箭头函数无this)、this[Symbol.species] = ...(实例属性无效)、get [Symbol.species]() { ... }(非 static) - 可运行验证:
MyArray[Symbol.species]应该是一个函数;typeof MyArray[Symbol.species]应为"function"。
观察方法是否“穿透”了自定义行为
如果子类添加了专属方法(比如 MyArray.prototype.getFirst),而 map 后的结果无法调用它,大概率是因为返回的是原生 Array。
-
const a = new MyArray(1,2); const b = a.map(x => x); b.getFirst(); // TypeError→ 说明b是Array实例,Symbol.species已生效(或未设置,回退到默认Array) - 若
b.getFirst()正常执行,说明map返回了MyArray,此时要确认是否显式设置了[Symbol.species]() { return this; }。
注意哪些方法会受它影响
不是所有方法都读取 Symbol.species。只限明确规范中指定使用它的内置方法:
-
Array:
map、filter、slice、concat、flat、flatMap -
Promise:
then、catch、finally -
RegExp:
replace(生成新正则时)、split(某些实现) -
Map / Set:
filter(非标准,但部分 polyfill 或引擎扩展可能支持) - 你自己写的
map方法不会自动读取它——必须手动实现逻辑:this.constructor[Symbol.species]。
相关文章
- 蚂蚁新村小课堂今日答案1月11日 以下哪一项是我国古人首创的造船技术 08-02
- 蚂蚁庄园答题今日答案2026年1月12日 08-02
- 蚂蚁庄园答案2026年1月12日 08-02
- 今日小鸡庄园答案2026.1.12 08-02
- 如何查看爱发电APP官方创作教程与作者经验分享 08-02
- 蚂蚁庄园小鸡答题今日答案2026年1月12日 08-02