javascript継承

8199 ワード

javascript継承
何が継承ですか相続はお父さんの多くのお金です.だからお父さんを受け継いで、金持ちの二代目になりました.お金持ちの主です.突然お父さんがワールドカップでボールを賭けました.負けてしまいました.それで、あなたも貧乏の卵になりました.これは継承非なり、非なり.
Cシシ継承
public class A {
   private int a;
   private int b;
}

public class B :A {
 private int c;
 private int b;
}

//B    A
ES 6継承
export default class A {
    constructor(props){
       super(props)
    }
    test() { alert('test') }
}

export default class B extends A {
    constructor(props){
       super(props)
    }
    test1() { this.test() }
}

//B    A
継承メカニズムの実現
ECMAScriptで継承機構を実現するには、継承する基質から着手することができます.すべての開発者が定義したクラスはベースクラスとして使用できます.安全のために、ローカルクラスとホストクラスはベースクラスとして使用できません.このように、共通のアクセスがコンパイルされたブラウザクラスのコードを防ぐことができます.これらのコードは悪意の攻撃に使用されます.ベースクラスを選択すると、そのサブクラスを作成できます.基本クラスを使うかどうかはあなたが決めます.場合によっては、直接使用できない基本クラスを作成したいかもしれません.サブクラスに共通の関数を提供するためにのみ使用されます.この場合、基質は抽象クラスと見なされる.
ECMAScriptは他の言語のように抽象類を厳密に定義していませんが、時には使用できない種類を作ることがあります.普通、私たちはこの種類を抽象類と呼びます.
作成したサブクラスは、構造関数および方法の実現を含む超クラスのすべての属性と方法を継承します.すべての属性と方法は共通であることを覚えてください.したがって、サブクラスは直接これらの方法にアクセスすることができます.サブクラスはまた、スーパークラスにない新しい属性と方法を追加することができます.また、スーパークラスの属性と方法をカバーすることもできます.
継承の方式
他の機能と同様に、ECMAScriptの継承方式は一つではない.これはJavaScriptにおける継承メカニズムが明確に規定されているのではなく、模倣によって実現されているからです.これは、すべての継承の詳細が完全に解釈プログラムによって処理されるわけではないことを意味する.開発者として、最適な継承方式を決定する権利があります.
一、対象を詐称する(構造相続)
「構造関数」というのは普通の関数ですが、内部ではthis変数が使われています.構造関数にnew演算子を使うと、インスタンスが生成され、this変数はインスタンスオブジェクトに結合されます.
原理:構造関数は、thisキーワードを使用して、すべての属性と方法に値を割り当てます.すなわち、クラス宣言の構造関数方式を採用します.コンストラクタは関数だけなので、クラスAコンストラクタをクラスBの方法にして呼び出します.クラスBはクラスAの構造関数で定義された属性と方法を受け取ります.
function ClassA(name){
    this.name = name;
    this.say = function(){
        console.log(this.name)
    }
}

function ClassB(name){
    this.newSay = ClassA
    this.newSay(name)
    delete this.newSay;
}
Class AのためにnewSay方法(関数名は彼のポインタだけを指す)を与えて、この方法を呼び出して、彼がClass Bコンストラクタのパラメータnameであることを伝えます.新しい属性と新しい方法はすべて新しい方法のコードラインの後で定義しなければなりません.
起動時:
var a = new ClassA('one')
var b = new ClassB('two')
a.say() //   'one'
b.say() //   'two'
対象と偽ると複数の継承が可能です.
function ClassA(name){
    this.name1 = name;
    this.say = function(){
        console.log(this.name1)
    }
}
function ClassB(name){
    this.name2 = name;
    this.method = function(){
        console.log(this.name2) //       name2    ClassA      ,      ClassA  
    }
}

function ClassC(name1,name2){
    this.newSay = ClassA
    this.newSay(name1)
    delete this.newSay;

    
    this.newMethod = ClassB
    this.newMethod(name2)
    delete this.newMethod
}
// test
var a = new ClassA('one')
var b = new ClassB('two')
var c = new ClassC('three','four')
a.say() //    'one'
b.method() //    'two'
c.say() //    'three'
c.method() //    'four'
弊害:二つのクラスがある場合、クラスAとクラスBは同名の属性または方法を持っています.クラスBは高い優先度を持っています.後のクラスから引き継がれるからです.このような小さな問題以外にも、対象と偽って多重継承メカニズムを実現するのは簡単である.この継承方法の流行によって、ECMAScriptの第三版はFunctionオブジェクトに二つの方法、すなわちcall()とappy()を加えました.
コール
function ClassA(name){
    this.name = name;
    this.say = function(){
        console.log(this.name)
    }
}

function ClassB(name){
    ClassA.call(this,name)  // ClassA   this      ClassB  
}

//test
var a = new ClassA('one')
var b = new ClassB('two')
a.say() //   'one'
b.say() //   'two'
appy()
function ClassA(name){
    this.name = name;
    this.say = function(){
        console.log(this.name)
    }
}

function ClassB(name){
    ClassA.apply(this,arguments)  //  ClassB     arguments              apply()   
}

//test
var a = new ClassA('one')
var b = new ClassB('two')
a.say() //   'one'
b.say() //   'two'
短所:プロトタイプチェーン上の属性と方法を継承できません.
二、プロトタイプチェーン継承
原理:このような形を継承するECMAScriptではもともとプロトタイプのオブジェクトはテンプレートであり、このテンプレートをベースに、プロトタイプオブジェクトの属性と方法はすべてそのクラスのすべてのインスタンスに渡されます.プロトタイプチェーンはこの機能を利用して継承機構を実現した.
対象と偽るのは似ていますが、サブクラスのすべての属性と方法はプロトタイプ属性が付与された後に現れなければなりません.その前に与えられた値のすべての方法が削除されますから.なぜですか?プロトタイプの属性が新しいオブジェクトに置き換えられているため、新しい方法を追加した元のオブジェクトは破棄されます.
注意:Class Aの構造関数を呼び出して、パラメータを伝えませんでした.これはプロトタイプチェーンにおいて標準的なやり方である.コンストラクタにはパラメータがないことを確認します.
function ClassA(){ }

ClassA.prototype.name = 'chuchur'
ClassA.prototype.say = function(){
    console.log(this.name)
}

function ClassB(){}
/**
 *      prototype      ,         。
 *    Cat.prototype.constructor == Animal   ==>true
 */
ClassB.prototype = new ClassA()

//           
/** 
 *     prototype      constructor  ,        
 *   ClassB.prototype = new ClassA(),  ClassB.prototype.constructor   ClassB,      ClassA
 *      ,         constructor  ,    prototype   constructor  。
 *     (new ClassB()).constructor == ClassA ==>true,
 *             ,          , ClassB.prototype   constructor   ClassB,
 *      prototype   ,     construcotr
*/
ClassB.prototype.constructor = ClassB

ClassB.prototype.name = ''
ClassB.prototype.method = function(){
    console.log(this.name)
}

//test
var a = new ClassA()
var b = new ClassB()
a.name = 'one'
b.name = 'two' //       , name    chuchur,       
a.say() //    one
b.say() //    two
b.method() //    two
短所:プロトタイプチェーンの弊害は多重継承をサポートしていません.プロトタイプチェーンは他のタイプのオブジェクトでタイプ別のプロトタイプの属性を書き換えます.
三、混合方式の継承
この継承方式は構造関数を用いてクラスを定義し,いかなるプロトタイプも使用しない.物体の偽善の主な問題は構造関数方式を使用しなければならないことであり、これは最良の選択ではない.プロトタイプチェーンを使うとパラメータ付きの構造関数が使えなくなります.
クラスを作成する一番いい方法は、構造関数で属性を定義し、原型で方法を定義することです.この方法は継承機構にも適用され、オブジェクトを用いて構造関数の属性を継承し、プロトタイプオブジェクトをプロトタイプチェーンで継承する方法である.
function ClassA(mail){
    this.mail = mail
}
ClassA.prototype.sayMail = function(){
    console.log(this.mail)
}

function ClassB(mail,name){
    ClassA.call(this,mail)
    this.name = name
}
ClassB.prototype = new ClassA()
ClassB.prototype.constructor = ClassB
ClassB.prototype.sayName = function(){
    console.log(this.name)
}

//test
var a = new ClassA('[email protected]')
var b = new ClassB('[email protected]','chuchur')
a.sayMail() //   [email protected]
b.sayMail() //   [email protected]
b.sayName() //   chuchur
ES 5継承とES 6継承の違い
class A {
    sayName(){
        console.log('chuchur')
    }
}

class B extends A {
  constructor() {
    super();
  }
}
ES 5の継承は、本質的には、サブクラスのインスタンスオブジェクトthisを作成してから、父親タイプの方法をthisに追加します.ES 6の継承メカニズムは全く違っています.実質的には、親のインスタンスオブジェクトの属性と方法を、thisの上に加えて、次にサブクラスの構造関数でthisを修飾して、親のすべての行為を継承することができます.
superを関数として呼び出した場合は、親の構造関数を表します.ES 6は、サブクラスの構造関数が一回のsuper関数を実行しなければならないと要求しています.
なお、superは親Aの構造関数を表しているが、サブクラスBの例、すなわちsuper内部のthisはBを指すので、super()はここでA.prototype.com nstructor.callに相当する.
superは対象としても使用できますが、このときsuperは一般的な方法の中でA.prototypeを指すので、super.sayNameはA.prototype.sayNameに相当します.
class A {
    sayName(){
        return 'chuchur'
    }
}

class B extends A {
  constructor() {
    super();
    console.log(super.sayName())
  }
}
ES 6は、オリジナルのコンストラクタ定義のサブクラスを継承することができ、オリジナルのデータ構造(Aray、Stringなど)のサブクラスをカスタマイズすることができます.これはES 5ではできません.extensのキーワードは、クラスを継承するだけでなく、元の構造関数を継承するために使用されます.したがって、元のデータ構造に基づいて、自分のデータ構造を定義することができます.
class SuperArray extends Array {
  constructor() {
    super();
    this.history = [[]];
  }
  commit() {
    this.history.push(this.slice());
  }
  revert() {
    this.splice(0, this.length, ...this.history[this.history.length - 1]);
  }
}

var x = new SuperArray();

x.push(1);
x.push(2);
x // [1, 2]
x.history // [[]]

x.commit();
x.history // [[], [1, 2]]
クラスのプロタイプの属性とプロト.属性
ブラウザのES 5が実装されている中、どのオブジェクトにも_u_u uがあります.プロト.属性は、対応するコンストラクタのプロトタイプ属性を指します.Classはコンストラクションのシンタックスキャンディーとして、プロトタイプの属性とプロト.属性を持つため、2つのチェーンが同時に存在します.
(1)サブクラスの_uプロト.属性は、構造関数の継承を表し、常に親を指します.
(2)サブタイププロタイプ属性の_u u_uプロト.属性は、方法の継承を表し、常に親タイプのプロトタイプ属性を指します.
class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
上のコードの中で、サブクラスBの_uプロト.属性は親タイプA、サブタイプBのプロトタイプ属性を指します.プロト.属性は親タイプAのプロタイプ属性を指します.
ES 5継承ES 6継承をグラフィックで表します.
実例解説
この記事に移ってください.js-継承-jquery
posted@
2019-03-02 18:08邱秋閲読(
…)コメント(
コレクションを編集