ES6的class继承中,如果不想调用super(),则唯一的方法是让类的构造函数返回一个对象,应该怎样理解?

在看 Nicholas C. Zakas 写的《深入理解ES6》第198页,关于类的继承中,有下面一段话:

如果不想调用 super() ,则唯一的方法是让类的构造函数返回一个对象。

这里说的返回一个对象是什么意思?是父类的构造函数返回一个对象还是子类的构造函数返回一个对象?

我父类和子类都试过返回一个对象,但是在子类中不调用 super() 依然会报错 Must call super constructor in derived class before accessing 'this' or returning from derived constructor 的错误。

class A {
  constructor () {
     return {}
  }
  sayName () {
    console.log(this.name)
  }
}

class B extends A {
  constructor () {
    this.name = 'test'
  }
}
阅读 10.2k
2 个回答

你既然在看《深入理解ES6》,应该是明白什么是super()super作为函数调用时,代表父类的构造函数,不过this指向的子类实例对象。所以如果你在B的constructor中执行super(),就相当于执行A.prototype.constructor.call(this)

如果你想构造个你描述的例子的话应该是这样的:

class A {
  constructor () {
     this.name='test'
  }
  sayName () {
    console.log(this.name)
  }
}

class B extends A {
  constructor () {
   return {awful:true};
  }
}
let child=new B();
console.log(child);
// {awful:true}
child instanceof B
//false
A.isPrototypeOf(B)
//true

现在虽然看上去B是继承了A的一个类,但是现在B已经起不到构造函数的作用了!你看到child instanceof B为false。
所以这句话的意思其实是:如果想用Class实现类的继承,那么在子类的构造函数中必须使用super()。否则你就只能通过让子类构造函数返回一个对象。而一旦你这么做,那么即使子类继承了父类(A.isPrototypeOf(B)为true),它也起不到构造函数的作用。

在es5中实现这一方式的代码是:

function C(){
this.x='test';
return {y:1};
}
new C();
//{y:1}

我来回答下,我从ES5的角度来回答。
楼主肯定知道,class就是构造函数的语法糖。
我们ES5使用new来实例化一个构造函数。

我直接贴ES5 new的模拟实现代码来看看

function objectFactory(){
  var obj = new Object();
  var Constructor = [].shift.call(arguments);
  obj.__proto__ = Constructor.prototype;
  var rest = Constructor.apply(obj, arguments);
  return typeof ret === 'object' ? ret : obj;
}

看最后一句,如果类的构造函数返回了一个object,那子类就初始化为这个object哦。

再详细的可以看这个文章:
https://github.com/mqyqingfen...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏