鍍金池/ 問答/HTML/ ES6的class繼承中,如果不想調(diào)用super(),則唯一的方法是讓類的構(gòu)造函

ES6的class繼承中,如果不想調(diào)用super(),則唯一的方法是讓類的構(gòu)造函數(shù)返回一個(gè)對(duì)象,應(yīng)該怎樣理解?

在看 Nicholas C. Zakas 寫的《深入理解ES6》第198頁,關(guān)于類的繼承中,有下面一段話:

如果不想調(diào)用 super() ,則唯一的方法是讓類的構(gòu)造函數(shù)返回一個(gè)對(duì)象。

這里說的返回一個(gè)對(duì)象是什么意思?是父類的構(gòu)造函數(shù)返回一個(gè)對(duì)象還是子類的構(gòu)造函數(shù)返回一個(gè)對(duì)象?

我父類和子類都試過返回一個(gè)對(duì)象,但是在子類中不調(diào)用 super() 依然會(huì)報(bào)錯(cuò) Must call super constructor in derived class before accessing 'this' or returning from derived constructor 的錯(cuò)誤。

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

class B extends A {
  constructor () {
    this.name = 'test'
  }
}
回答
編輯回答
舊城人

你既然在看《深入理解ES6》,應(yīng)該是明白什么是super()super作為函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù),不過this指向的子類實(shí)例對(duì)象。所以如果你在B的constructor中執(zhí)行super(),就相當(dāng)于執(zhí)行A.prototype.constructor.call(this)

如果你想構(gòu)造個(gè)你描述的例子的話應(yīng)該是這樣的:

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

現(xiàn)在雖然看上去B是繼承了A的一個(gè)類,但是現(xiàn)在B已經(jīng)起不到構(gòu)造函數(shù)的作用了!你看到child instanceof B為false。
所以這句話的意思其實(shí)是:如果想用Class實(shí)現(xiàn)類的繼承,那么在子類的構(gòu)造函數(shù)中必須使用super()。否則你就只能通過讓子類構(gòu)造函數(shù)返回一個(gè)對(duì)象。而一旦你這么做,那么即使子類繼承了父類(A.isPrototypeOf(B)為true),它也起不到構(gòu)造函數(shù)的作用。

在es5中實(shí)現(xiàn)這一方式的代碼是:

function C(){
this.x='test';
return {y:1};
}
new C();
//{y:1}
2017年10月19日 21:46
編輯回答
綰青絲

我來回答下,我從ES5的角度來回答。
樓主肯定知道,class就是構(gòu)造函數(shù)的語法糖。
我們ES5使用new來實(shí)例化一個(gè)構(gòu)造函數(shù)。

我直接貼ES5 new的模擬實(shí)現(xiàn)代碼來看看

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;
}

看最后一句,如果類的構(gòu)造函數(shù)返回了一個(gè)object,那子類就初始化為這個(gè)object哦。

再詳細(xì)的可以看這個(gè)文章:
https://github.com/mqyqingfen...

2017年1月7日 22:08