JS-クラス - 継承と発展モデル

 

メソッド継承された詳細な研究のJS

(前2015標準)の1つのES5実装

JS複合オブジェクトはプロトタイプチェーンの方法によって達成される、関数法のprototype サブクラスに格納されたプロトタイプの__proto__コンストラクタでは、コンストラクタ関数を使用しなければならないnewキー

1.1プロトタイプチェーン

function Parent () {
    this.name = 'haha';
    this.car = ['area', 'auto'];
}
Parent.prototype.getinfo = function () {
    return `name:  ${this.name} + age: ${this.car}`;
}

function Child () {
    this.name  = 'heihei';
}
Child.prototype = new Parent();
var child = new Child();
child.getinfo(); // name: heihei car: area auto;

var childOther = new Parent();
childOther.car.push('bmw');
child.getinfo(); // name: heihei car: area auto bmw;
  • 短所:1は、親クラス2、すべてのサブクラスで共有クラス属性値にパラメータを渡すことはできません

コンストラクタ1.2

function Parent (name) {
    this.name = name;
    this.car = ['area','auto'];
}

function Child (name) {
    Parent.call(this, name);
}
var child1 = new Child('haha');
var child2 = new Child('heihei');

child1.push('bmw');
child2.car;  //  area auto

  • 短所:この方法は、対応するコンストラクタを呼び出し、継承されていないプロトタイプのコピーを継承することはできません。

1.3複合

function Parent (name) {
    this.name = name;
    this.car = ['area', 'auto'];
}
Parent.prototype.getinfo = function () {
    return `name: ${this.name} + car: ${this.car}`;
}

function Child (name) {
    Parent.call(this, name);
}
Child.prototype = new Parent();
var child1 = new Child('haha');
child1.getinfo();  // name: haha + car: area auto
var child2 = new Child('heihei');
child2.car.push('bmw');
child1.getinfo();  // name: haha + car: area auto 
child2.getinfo();  // name: haha + car: area auto bmw 

  • 短所:欠陥のある2つの親クラスのサブクラスの属性情報、

1.4寄生合成

function Parent (name) {
    this.name = name;
    this.car = ['area', 'auto'];
}
Parent.prototype.getinfo = function () {
    return `name: ${this.name} + car: ${this.car}`;
}

function Child (name) {
    Parent.call(this, name);
}

<!-- 关键点:单独创建constructor,并继承父类然后赋给子类原型 -->
var proto = Object.create(Parent.prototype);
proto.constructor = Child;
Child.prototype = proto;

var child1 = new Child('haha');
child1.getinfo(); // name: haha + car: area auto
var child2 = new Child('heihei');
child2.getinfo(); // name: heihei + car; area autp
child2.car.push('bmw');
child1.getinfo(); // name: haha + car: area auto
  • 短所:基本的には完璧

1.5プロトタイプ式

function Parent() {
    this.name = 'haha';
    this.car = ['area', 'auto'];
}

var child = Object.create(new Parent());
child.attr1 = 'new job';

若しくは

function Parent () {
    this.name = 'heihei';
    this.car = ['auto'];
}
function deget (obj) {
    var F = function () {};
    F.prototype = obj;
    return new F();
}
var child = deget(new Parent());
child.attr1 = 'new job';
  • 短所:オブジェクト内に存在する導出オブジェクトは、親オブジェクトは、オブジェクトのプロトタイプとして機能する、プロトタイプインスタンス属性は、現在の属性を追加され、再利用できないすべてのインスタンスによって共有され、機能パッケージはありません

1.6寄生

function beget(obj) {
    var F = function(){};
    F.prototype = obj;
    return new F();
}
function Super() {
    this.val = 1;
    this.arr = [1];
}

function getSubObject (obj) {
    var clone = beget(obj);
    clone.attr1 = 1;
    clone.attr2 = 2;

    return clone;
}
var sub = getSubObject(new Super());
console.log(sub.val);
console.log(sub.arr);
console.log(sub.attr1);

  • 原則:オブジェクトを作成する - >強化 - >リターンオブジェクト
  • 短所:再利用することはできません

2 ES6実装(ES2015)

2.1クラスを宣言

  • クラスを定義するには、次のように宣言し、クラスのキーワードが必要になります。
// 类的名称按照原则和编程习惯首字符应该大写!
class Error {
  // constructor中添加初始化类实例的时候,需要传入的变量
  constructor(type, date, source) {
      this.type = type;
      this.date = date;
      this.source = source;
  }
}
  • 式のクラス宣言
// 声明匿名的类
let Rect = class {
    constructor (height) {
        this.height = height;
    }
};
let r = new Rect(100);
 
 // 声明具名的类
let RectAngle = class Rect {
    constructor (width) {
        this.width = width;
    }

    getClassName () {
        return Rect.name;
    }
}

  • 宣言型ステートメントの二種類以上進まなくなり、私たちは、最初に宣言しなければなりません。
  • そして、文のエラー、クラス名がメモリに書き込まれます、それは間違ったクラス名が取られていることです。

コンストラクタが必要かどうか?

このクラスは、コンストラクタメソッドを持っている必要があります!宣言がコンストラクタは静かにコンストラクタが追加されます表示されていない場合は 関数にクラスと同等、コンストラクタがあるでしょう、このコンストラクタに戻り、デフォルトの戻り値を変更することができますし、この方法は、内部の親クラスから継承しているサプレ

2.2クラス本体と、前記

  • ステートメントと式strictモードがデフォルトのメインクラスがstrictモードで実行されている、傾向はES6のためです。コンストラクタ、静的メソッド、プロトタイピング、ゲッター、セッターは、厳密モードで実行されています。

  • オブジェクトを作成し、初期化するために使用される特別なクラスのコンストラクタメソッド。各クラスには、複数のコンストラクタは、構文エラーを報告しますしているだけで1つのコンストラクタを持つことができます。コンストラクタは使用することができますsuperコンストラクタキーワードは親クラスを呼び出します。

  • getterメソッドとsetterメソッド

class Rect {
    constructor () {
        //  ...声明类的属性
    }

    // 使用 get set 关键字,对某个属性进行存值和取值时,执行相应操作
    get prop () {
        return '获取prop';
    }

    set prop (value) {
        console.log('setter: ', value);
    }

}

var rectIns = new Rect();
rectIns.prop;  // 获取prop
rectIns.prop = '新的prop'; // setter: 新的prop

  • プロパティのクラス class属性包括3种:静态属性,实例属性,原型属性。

  • アクセスをプロパティと割り当て

类的属性不能通过super作为对象的时候访问,实例属性可以通过super对象的时候给子类添加属性,然后还是用this访问!

class Animal {
    constructor () {
        this.name = 'history'
    }
    myDog () {
        console.log(333);
    }
}
class Dog extends Animal {
    constructor () {
        super();
        this.childName = 'now';

    }
    setSuper () {
        super.newName = '666';
    }
    getSuper () {
        console.log(this.newName);     //666
        console.log(this.childName);   //now
        console.log(this.name);        //history
        console.log(super.name);       //undefined
        console.log(super.childName);  //undefined
        console.log(super.newName);    //undefined
    }
}

var dog = new Dog();
dog.getSuper();

2.3クラスの静的メソッド

の静特性

静态方法的创建和引用方式,直接作用在函数或者类上
实例方法和属性在constructor或者原型上
静态方法不能被类的实例使用
实例方法和属性也不能被静态方法使用
静态方法和属性可以被子类继承
静态方法可调用静态属性

次のとおりであり、静的メソッドと静的プロパティを宣言します。

class Animal {
    // 定义静态方法
    static getsomething () {
        console.log('exe static function: ', this.feature);
    }
}
// 不能在class内部定义static变量
Animal.feature = 'staticAttrs';
Animal.getsomething(); // exe static function: staticAttrs

静的メソッドとクラスのプロパティ、メソッド、および同じ名前のインスタンス属性は、静的な方法でぶら下がって、二つの異なる空間ためであってもよいFunction、吊り例示的な方法Objectに関する。お互いあまり訪問し、あなたは未定義のプロンプトが表示されます。

2.4クラスの継承

  • クラス継承は、superキーワードを使用し、栗のキーワードを拡張する必要があります
class Animal {
    constructor(height, weight) {
        this.height = height;
        this.weight = weight;
    }
}

class Dog extends Animal {
    constructor(height, weight, color) {
        // super声明在前
        super(height, weight);
        this.color = color;
    }
    // 这个方法默认放在父类的原型上
    generateAnimal () {
        return this.color;
    }
}

let labuladuo = new Dog(1, 30, 'brown');

labuladuo instanceof Animal;
labuladuo instanceof Dog;

、スーパー()コンストラクタ重要な役割同様の継承A.prototype.constructor.call(本)(または元の継承JS)を超()親クラスのコンストラクタを使用して独自のコンストラクタを生成し、修正再表示この後にします。カラー=色、自分のコンストラクタを持っています

super.x = '子类super赋值等同于给this赋值';

class B extends A {
  constructor() {
    super();
    this.x = 2;
    super.x = 3;
    console.log(super.x); // undefined
    console.log(this.x); // 3
  }
}

A.prototype =新しいB()のプロトタイプは、新しいB(まで延長される場合は、継承するプロトタイプチェーン)のような使い方が宣言する必要がありますが、違いの本質と非常によく似てカバーしています。

  • サブクラスオブジェクトとして後のスーパースーパースーパーキーワード()は、プロトタイプの親クラス・ポイント、スーパー自体が目的であると考えることができます
super.height === Animal.prototype.height  // true

super動物は、表現するが、親クラスを意味するものではありませんprototypeしたがって、本実施形態のsuper.generateAnimalによってサブクラス()メソッドは、親クラスのプロトタイプを呼び出すことができます。

  • super プロパティの例としては、アクセスまたは親クラスのコンストラクタのサブクラスすることができません。

  • super それ以外の場合はエラーがあるだろう、関数とオブジェクトとして、スーパー2つのデフォルトの属性がありますが、それは暗黙的に指定する必要があります。何ジェスチャーは、使用することはできません。

  • 静的スーパー静的メソッド場合は、次のように、静的メソッドは、親クラスを継承します。

class Animal {
    static myDog (dog) {
        console.log('static function: ', dog);
    }
    myDog (dog) {
        console.log('instance function: ', dog);
    }
}
class Dog extends Animal {
    static myDog (dog) {
        super.myDog(dog)
    }
}
Dog.myDog('labuladuo');  // static function: labuladuo

2.5クラスのプロトタイプと__proto__

  • 1プロトタイプチェーン)サブクラスはJSに継承__proto__継承2)コンストラクタサブクラス表し、親クラスにポイントprototype__proto__親クラスにポイントをprototype表現、例えば、継承します
class A {}
class B extends A {}
B.__proto__ === A // true
b.prototype.__proto__ === A.prototype  // true

2.6連続ネイティブコンストラクタ

コンストラクタネイティブ前記の9種類

Boolean
String
Number
Array
RegExp
Date
Error
Object
Function

Errorオブジェクトを作成エクステンション

class ExtendError extends Error {
    constructor (message) {
        super();
        this.name = this.constructor.name;
        this.message = message;
        this.stack = (new Error()).stack;
    }
}   

var myError = new ExtendError('12');
myError.message; // '12'
myError instanceof Error;  // true 
myError.stack;  
// "Error
//     at new ExtendError (<anonymous>:6:23)
//     at <anonymous>:10:15"

そのようなパラメータとしてDOMノードオブジェクト、工具マガジンの拡張ノード継承親クラスとしてノードを動作させる方法として、拡張工具マガジン(カスタムツールマガジン)。

おすすめ

転載: www.cnblogs.com/the-last/p/11204549.html