继承内置类如Array需在constructor中用Reflect.construct(Array, args, new.target)返回实例,否则无法激活内部槽位和数组特性;仅extends+super会导致length不更新、索引赋值无效、Array.isArray()返回false等问题。

继承内置类需绕过默认限制
直接用 class MyArray extends Array 声明子类,语法上合法,但实例行为异常:长度不自动更新、索引赋值无效、instanceof Array 为 true,但 Array.isArray() 返回 false(ES2015+ 已修复该问题,但部分旧环境或特殊操作仍可能出错)。根本原因是 JavaScript 内置构造函数(如 Array、Error、Map)内部使用了特殊的 [[Construct]] 行为,普通 super() 调用无法完全复现其初始化逻辑。
必须在 constructor 中返回 new.target 实例
正确做法是:子类 constructor 中调用 super() 后,**显式返回 Reflect.construct(Array, args, new.target)**。这确保底层引擎用原生数组逻辑创建对象,而非普通对象包装。
- 不写
return→ 得到普通对象,失去数组方法和 length 响应性 - 只写
super(...args)→ this 是普通对象,无法触发 Array 的内部槽位(internal slots)初始化 - 正确写法:在
super()后立即return Reflect.construct(Array, args, new.target)
完整可运行示例
以下代码让自定义类具备完整数组行为:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
class MyArray extends Array {
constructor(...args) {
const instance = Reflect.construct(Array, args, new.target);
// 可在此添加自定义初始化逻辑,如设置私有属性
instance._createdAt = Date.now();
return instance;
}
customMethod() {
return `Size: ${this.length}, created at ${this._createdAt}`;
}
}
const arr = new MyArray(1, 2, 3);
console.log(arr); // [1, 2, 3]
console.log(arr.length); // 3
console.log(arr[0]); // 1
arr.push(4);
console.log(arr); // [1, 2, 3, 4]
console.log(Array.isArray(arr)); // true
console.log(arr instanceof MyArray); // true
console.log(arr instanceof Array); // true
为什么不能只靠 extends + super?
因为 Array 等内置类的实例依赖引擎内部的“数组 exotic object”机制,包括:
立即学习“Java免费学习笔记(深入)”;
- 自动同步
length与数字索引属性 - 对
push、pop、splice等方法的特殊处理 - 内部 [[DefineOwnProperty]] 钩子拦截索引赋值
这些机制仅在通过原生构造器(或 Reflect.construct 模拟原生构造)创建时激活。单纯继承原型链无法触发它们。

















