JavaScript中继承含默认构造函数的类为何出现编译错误?
super()导致的this使用错误 问题描述
我尝试在JavaScript中创建子类时,遇到了子类构造函数里使用this相关的错误,代码如下:
class Mammals { // 未显式定义构造函数 } class Humans extends Mammals { constructor(name) { this.name = name; } } const jimmy = new Humans("Jimmy"); console.log(jimmy.name);
我原本认为如果基类有默认无参构造函数,JavaScript应该允许子类构造函数无需显式调用super()。由于Mammals未显式定义构造函数,具备默认构造函数,所以我觉得Humans构造函数不需要调用super(),但仍遇到错误提示:
Must call super constructor in derived class before accessing 'this'
or returning from derived constructor
能否有人解释原因?
感谢您的帮助!
解答
这是JavaScript类继承的强制规则:只要子类显式定义了自己的构造函数,就必须在访问this或者从构造函数返回之前调用super(),和父类是否有显式构造函数无关。
当父类没有显式构造函数时,JavaScript确实会自动生成一个默认的无参构造函数,但这个默认构造函数的存在不代表子类可以跳过super()的调用——子类的this对象是基于父类实例初始化而来的,只有先调用super()完成父类的初始化流程,this才能被正确绑定到子类实例上,此时你才能安全地使用this添加属性。
你只需要在子类构造函数里先调用super(),再操作this即可解决问题:
class Mammals { // 未显式定义构造函数 } class Humans extends Mammals { constructor(name) { super(); // 先调用super()完成父类初始化 this.name = name; } } const jimmy = new Humans("Jimmy"); console.log(jimmy.name); // 输出 "Jimmy"
另外补充一种情况:如果子类没有显式定义构造函数,JavaScript会自动生成一个默认构造函数,这个默认构造函数会自动调用super()并传递所有传入的参数,这种情况下你就不需要手动写super()了,比如:
class Mammals { } class Humans extends Mammals { // 无自定义构造函数,使用默认构造函数 } const jimmy = new Humans();
内容的提问来源于stack exchange,提问作者jimo

