关于ES2015构造器返回对象时super()调用的this替换机制的疑问
关于ES2015构造器中super()替换this的原理解释
先把手册那段话拆成两部分理解:
1. 为什么父类构造器会替换子类的this?
ES2015(ES6)里,当子类构造函数调用super(...)时,如果父类构造函数返回了一个对象(而非默认的this),这个返回的对象会直接替换子类原本初始化好的this。
这是原生JS的特性,比如Array、Map这类内置对象的构造函数,返回的是引擎内部特殊处理的实例,不是普通构造函数里的this。如果子类不接受这个替换,继续用自己的this,就会和父类实例完全脱节,继承关系直接失效。
举个原生JS的例子:
class MyArray extends Array { constructor(size) { super(size); // 此处super()返回Array实例,直接替换子类的this this.tag = 'custom-array'; } } const arr = new MyArray(3); console.log(arr.tag); // 'custom-array' console.log(arr.push('test')); // 4(能正常调用Array方法,说明继承有效)
2. TypeScript生成的代码为什么要处理这个?
TypeScript转译类继承代码时,必须显式捕获super(...)的返回值并赋值给子类的this。如果不这么做,在旧环境或特殊父类场景下,子类的this会变成一个无意义的空对象,根本没法继承父类的属性和方法。
转译后的简化代码大概是这样:
function MyArray(size) { let _this; // 捕获super的返回值,替换子类的this _this = super(size); _this.tag = 'custom-array'; return _this; } // 绑定原型链完成继承 MyArray.prototype = Object.create(Array.prototype); MyArray.prototype.constructor = MyArray;
简单总结:父类构造器如果返回对象,这个对象就是子类实例的真实载体;TypeScript必须主动接住这个返回值,确保子类的this指向正确实例,否则继承会彻底失效。
内容的提问来源于stack exchange,提问作者NeoZoom.lua
相关产品推荐
相关产品推荐

