国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ES6 class extends

Big_fat_cat / 2336人閱讀

摘要:解決方案借用構(gòu)造函數(shù)組合繼承寄生組合式繼承原型鏈繼承欠圖一張從來說,實(shí)現(xiàn)對象的繼承,還是相當(dāng)麻煩的。分析基類創(chuàng)建的值,然后派生類的構(gòu)造函數(shù)再修改這個(gè)值。

繼承 inherit

class 是對原型繼承的一種語法糖的包裝。那相對于原型繼承,它有什么優(yōu)點(diǎn)呢?
我們來先看一個(gè)典型的基于原型鏈繼承的例子。部分內(nèi)容來自“Javascript高級(jí)程序設(shè)計(jì)”

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
}

function SubType() {
    this.subProperty = false;
}

SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function() {
    return this.subProperty;
}

var instance = new SubType();
console.log(instance.getSuperValue());  // true
console.log(instance instanceof Object);  // true
console.log(instance instanceof SuperType);  // true
console.log(instance instanceof SubType);  // true

問題,當(dāng)包含引用類型的值。

function SuperType() {
    this.colors = ["red", "blue", "green"];
}

function SubType() {
   
}

SubType.prototype = new SuperType();


var instance = new SubType();
instance.colors.push("black");
var instance1 = new SubType();
instance1.colors.push("white");
console.log(instance.colors);  // [ "red", "blue", "green", "black", "white" ]
console.log(instance1.colors);  // [ "red", "blue", "green", "black", "white" ]

解決方案:

借用構(gòu)造函數(shù)

function SuperType() {
    this.colors = ["red", "blue", "green"];
}

function SubType() {
   SuperType.call(this);
}

SubType.prototype = new SuperType();


var instance = new SubType();
instance.colors.push("black");
var instance1 = new SubType();
instance1.colors.push("white");
console.log(instance.colors);
console.log(instance1.colors);

組合繼承

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {    
    console.log(this.name);
}

function SubType(name, age) {
   SuperType.call(this, name);
   this.age = age;
}

SubType.prototype = new SuperType();
SubType.prototype.sayAge = function() {
    console.log(this.age);
}

寄生組合式繼承

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function inheritPrototype(subType, superType) {
    let prototype = object(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {    
    console.log(this.name);
}

function SubType(name, age) {
   SuperType.call(this, name);
   this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
    console.log(this.age);
}
var instance = new SubType("Tom", 70);
instance.colors.push("black");
var instance1 = new SubType("Jerry", 69);
instance1.colors.push("white");
console.log(instance.colors);
console.log(instance.sayName());
console.log(instance.sayAge());
console.log(instance1.colors);
console.log(instance1.sayName());
console.log(instance1.sayAge());

MDN 原型鏈繼承
(欠圖一張)

extends

從es5來說,實(shí)現(xiàn)對象的繼承,還是相當(dāng)麻煩的。而extends 關(guān)鍵字的出現(xiàn),使繼承變得簡單,原型會(huì)自動(dòng)進(jìn)行調(diào)整,super()/super關(guān)鍵字可以訪問父類的構(gòu)造方法和屬性。

class Animal { 
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(this.name + " makes a noise.");
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + " barks.");
  }
}

var d = new Dog("Mitzie");
d.speak();// "Mitzie barks."

分析:Dog類沒有構(gòu)造函數(shù),這樣合理嗎?

// 等價(jià)于上個(gè)類定義
class Dog extends Animal {
  constructor(name) {
    super(name)
  }
  speak() {
    console.log(this.name + " barks.");
  }
}

super()方法調(diào)用注意:

只可在以extends 實(shí)現(xiàn)的派生類中的constructor方法中調(diào)用,在非派生類或方法中直接調(diào)用,會(huì)報(bào)錯(cuò)。

在constructor中訪問this之前,一定要先調(diào)用super(),因?yàn)樗?fù)責(zé)初始化this,如果在super()調(diào)用之前嘗試訪問this,會(huì)報(bào)錯(cuò)。

如果不想調(diào)用super(),則唯一的方法是讓類的constructor()返回一個(gè)對象。

類方法遮蔽

說明:派生類中的方法總會(huì)覆蓋基類中的同名方法。

class Animal { 
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(this.name + " makes a noise.");
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + " barks.");
  }
}
// 基類中的speak()方法被覆蓋
靜態(tài)類成員繼承

說明:如果基類有靜態(tài)成員,那么這些靜態(tài)成員在派生類中也可用。

class Animal { 
    constructor(name) {
      this.name = name;
    }
    
    speak() {
      console.log(this.name + " makes a noise.");
    }
    static create(name) {
        return new Animal(name);
    }
  }
  
  class Dog extends Animal {
    speak() {
      console.log(this.name + " barks.");
    }
  }

  let a1 = Animal.create("Monkey");
  let a2 = Dog.create("BeijinDog");
  console.log(a1 instanceof Animal);  // true
  console.log(a2 instanceof Animal);  // true
  console.log(a2 instanceof Dog);  // false 這個(gè)是不是很意外?
派生自表達(dá)式的類

由ES6的class定義可以知道,是function的語法糖,但為實(shí)現(xiàn)原型繼承,提供了方便的實(shí)現(xiàn)。JS的強(qiáng)大的一點(diǎn)就是函數(shù)可以返回函數(shù),那如果返回類的定義呢?是否支持繼承?返回對象是個(gè)函數(shù),并且有[[Constrcutor]]屬性和原型,就能滿足extends實(shí)現(xiàn)。

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + " makes a noise.");
  }
}

function getBase() {
  return Animal;
}
class Dog extends getBase() {
  speak() {
    console.log(this.name + " barks.");
  }
}

const dog = new Dog("Tom");
dog.speak();

如果這個(gè)例子基于class的實(shí)現(xiàn),有點(diǎn)取巧的意思,那看另一個(gè)例子。

const SerializableMixin = {
  serialize() {
    return JSON.stringify(this);
  }
}

const AnimalMixin = {
  speak() {
    console.log(this.name + " barks.");
  }
}

function mixin(...mixins) {
  const base = function() {};
  Object.assign(base.prototype, ...mixins);
  return base;
}

class Dog extends mixin(AnimalMixin, SerializableMixin) {
  constructor(name){
    super(name);
    this.name = name;
  }
}

const dog = new Dog("Tom");
dog.speak();  // Tom barks.

關(guān)于function,class,extends,mixin,是否有新的理解呢?

內(nèi)建對象繼承

在ES6之前,內(nèi)建對象很難實(shí)現(xiàn)繼承的,更多用has-a思想,實(shí)現(xiàn)對內(nèi)建對象的處理。ES6中,大量內(nèi)建對象的內(nèi)部實(shí)現(xiàn)得以暴漏,也使得繼承內(nèi)建對象變成了可能。

class ColorsArray extends Array {
}
const colors = new ColorsArray();
colors[0] = "red";
console.log(colors.length); // 1

colors.length = 0;
console.log(colors[0]); // undefined

分析:基類(Array)創(chuàng)建 this 的值,然后派生類的構(gòu)造函數(shù)(ColorsArray)再修改這個(gè)值。所以一開始可以通過this訪問基類的所有內(nèi)建功能,然后再正確地接收所有與之相關(guān)的功能。這與Array.apply/call 這種方法實(shí)現(xiàn)繼承的this處理方式正好相反。這也是extends特殊的地方。

Symbol.species
class ColorsArray extends Array {
}
const colors = new ColorsArray("red", "green", "blue");
const subColors = colors.slice(0,1);
console.log(colors instanceof ColorsArray);  // true
console.log(subColors instanceof ColorsArray);  // true

通常來講,slice 方法繼承自 Array ,返回的應(yīng)該是Array的實(shí)例,但在這個(gè)示例中,卻返回的是ColorsArray的實(shí)例,這是為什么呢?這是ES6中Symbol.species的功勞。Symbol.species MDN 詳細(xì)說明

class MyArray extends Array {
  // Overwrite species to the parent Array constructor
  static get [Symbol.species]() { return Array; }
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x * x);

console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array);   // true

注意:重寫實(shí)現(xiàn)的時(shí)候,使用getter+static,可以返回想用的類型,也可以返回 this,是的,你沒看錯(cuò),在static getter中使用了this,它指向的是MyArray的構(gòu)造函數(shù)。

constructor中new.target

new.target是es6中新添加的元屬性,只有通過new操作創(chuàng)建對象的時(shí)候,new.target才會(huì)被指向類/方法本身,通過call/apply操作,new.target為undefined。可以通過判斷new.target,來確實(shí)函數(shù)是否允許new操作。MDN new.target 說明
慣例,再加個(gè)代碼示例,偷懶,直接從MDN上拷了。

function Foo() {
  if (!new.target) throw "Foo() must be called with new";
  console.log("Foo instantiated with new");
}

new Foo(); // logs "Foo instantiated with new"
Foo(); // throws "Foo() must be called with new"

又是先說function,不是已經(jīng)升級(jí)到ES6,使用class了嗎?始終要有一個(gè)清楚的認(rèn)識(shí),class,是function實(shí)現(xiàn)原型繼承的語法糖,但有自己的特性存在的(不然,也不用引入class了)。

class A {
  constructor() {
    console.log(new.target.name);
  }
}

class B extends A { constructor() { super(); } }

var a = new A(); // logs "A"
var b = new B(); // logs "B"

class C { constructor() { console.log(new.target); } }
class D extends C { constructor() { super(); } }
 
var c = new C(); // logs class C{constructor(){console.log(new.target);}}
var d = new D(); // logs class D extends C{constructor(){super();}}

這個(gè)就是類的了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/105822.html

相關(guān)文章

  • ES6class與面向?qū)ο缶幊蹋?)

    摘要:接下來我們看下類的寫法,這個(gè)就很接近于傳統(tǒng)面向?qū)ο笳Z言了。如果你想了解傳統(tǒng)面向?qū)ο笳Z言,這里是一個(gè)好切入點(diǎn)。作為對象時(shí),指向父類的原型對象。這些就是為將來在中支持面向?qū)ο蟮念悪C(jī)制而預(yù)留的。 在ES5中,我們經(jīng)常使用方法或者對象去模擬類的使用,并基于原型實(shí)現(xiàn)繼承,雖然可以實(shí)現(xiàn)功能,但是代碼并不優(yōu)雅,很多人還是傾向于用 class 來組織代碼,很多類庫、框架創(chuàng)造了自己的 API 來實(shí)現(xiàn) c...

    wangjuntytl 評論0 收藏0
  • [譯]在 React.js 中使用 ES6+

    摘要:如果是在中,我們也許只能這樣做但是,在中,我們不僅可以在對象字面量屬性的定義中使用表達(dá)式,還有使用使用字符串模板析構(gòu)擴(kuò)展運(yùn)算符我們在編寫組件的過程中,經(jīng)常遇到要從父組件要把自己的很多屬性多傳給子組件的情況。 原文地址: http://babeljs.io/blog/2015/06/07/react-on-es6-plus/ showImg(http://7xiyp1.com1.z0.g...

    Enlightenment 評論0 收藏0
  • ES6 class繼承與super關(guān)鍵詞深入探索

    摘要:請看對應(yīng)版本干了什么可知,相當(dāng)于以前在構(gòu)造函數(shù)里的行為。這種寫法會(huì)與上文中寫法有何區(qū)別我們在環(huán)境下運(yùn)行一下,看看這兩種構(gòu)造函數(shù)的有何區(qū)別打印結(jié)果打印結(jié)果結(jié)合上文中關(guān)于原型的論述,仔細(xì)品味這兩者的差別,最好手動(dòng)嘗試一下。 ES6 class 在ES6版本之前,JavaScript語言并沒有傳統(tǒng)面向?qū)ο笳Z言的class寫法,ES6發(fā)布之后,Babel迅速跟進(jìn),廣大開發(fā)者也很快喜歡上ES6帶...

    jubincn 評論0 收藏0
  • [譯]React ES6 class constructor super()

    摘要:當(dāng)我們在寫時(shí)候會(huì)用到中的語法比較常見的情況如下這里有兩個(gè)問題是否有必要在中調(diào)用函數(shù)調(diào)用和有何區(qū)別解答只有當(dāng)你有一個(gè)時(shí)候調(diào)用才是必須的看代碼上述代碼完全符合規(guī)定所以你其實(shí)并沒有必要去為你創(chuàng)建的每個(gè)調(diào)用話分兩頭如果你的代碼中有你就必須調(diào)用出現(xiàn)上 當(dāng)我們在寫React時(shí)候 會(huì)用到ES6中的class語法 ,比較常見的情況如下: class MyClass extends React.Comp...

    justjavac 評論0 收藏0
  • ES6 系列之 Babel 是如何編譯 Class 的(下)

    摘要:以上的代碼對應(yīng)到就是調(diào)用父類的值得注意的是關(guān)鍵字表示父類的構(gòu)造函數(shù),相當(dāng)于的。舉個(gè)例子這是因?yàn)樽鳛闃?gòu)造函數(shù)的語法糖,同時(shí)有屬性和屬性,因此同時(shí)存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 前言 在上一篇 《 ES6 系列 Babel 是如何編譯 Class 的(上)》,我們知道了 Babel 是如何編譯 Class 的,這篇我們學(xué)習(xí) Babel 是如何用 ES5 實(shí)現(xiàn)...

    endiat 評論0 收藏0

發(fā)表評論

0條評論

Big_fat_cat

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<