ECMAScript 6(25)class継承
7332 ワード
1.class継承
1.1継承とはは2つのクラスを定義し、1つのクラスには別のクラスの大部分の方法と属性が含まれているので、2つの方法と属性の繰返し度の高いクラスを定義するのは少しもったいない. は、Aクラスのメソッドを継承することによってBに継承する、BはAクラスのメソッドと属性を使用することができ、これが継承である.BはAを継承し、Aは親類、B子類と呼ぶ. es 5はどのように継承を実現するか、2つのコンストラクション関数を定義し、サブクラスでapplyを使用して親クラスを呼び出し、親クラスthisが実装属性の継承を指すことを再定義し、その後、子クラスのprototype=親クラスのprototype実装方法の継承を定義するが、これによりサブクラスのprototypeが書き換えられ、サブクラスがメソッドを追加するにはこのステップの後でなければならない.これもes 5継承の不足点である. es 6はextendsキーワードによって直接実現され、文法はより簡単で直接的である.
1.2 class継承(extends)
サブクラスextends親
1.3 constructor classでは、サブクラスがconstructorメソッドを書かない場合、デフォルトでは親constructor が継承されます.ただしconstructorメソッドが書かれている場合はsuperメソッドを呼び出す必要があります.そうしないと、インスタンスを新規作成するときにエラーが発生します. 理由:これは、サブクラス独自のthisオブジェクトが、親の構造関数によって作成され、親と同じインスタンス属性と方法が得られ、その後、それを加工し、サブクラス独自のインスタンス属性と方法を加えなければならないためです.superメソッドを呼び出さないと、サブクラスはthisオブジェクトを取得できません. サブクラスのコンストラクション関数では、superを呼び出した後にのみthisキーワードを使用できます.そうしないと、エラーが表示されます.これは、サブクラスインスタンスの構築であり、親インスタンスに基づいてsuperメソッドのみが親インスタンスを呼び出すことができるためです. ES 5の継承は、本質的にはサブクラスのインスタンスオブジェクトthisを作成してから、親クラスのメソッドをthisに追加します(Parent.apply(this)).ES 6の継承メカニズムはまったく異なり、実質的には親インスタンスオブジェクトの属性とメソッドをthisに追加し(superメソッドを呼び出す必要がある)、次にサブクラスの構造関数でthisを変更する. es 5は、まず子を構築する後に親を継承し、その後改造し、es 6はまず親を継承した後に子を構築し、その後改造 .
1.4親と子の関係 es 6は、この2つの条件を満たす を継承する.親のメソッドと属性布団クラス継承 親の静的メソッドで、布団クラスが継承されます.
Es 6の2つの条件は、
B.proto==A//true静的メソッドはB.prototypeを継承する.proto === A.prototype;//trueプロパティメソッド継承
1.5 Object.getPrototypeOf() Object.getPrototypeOfメソッドは、子クラスから親クラスを取得するために使用できます. は、1つのクラスが別のクラスを継承しているかどうかを判断するためにこの方法を使用することができる.
1.6 extendsを使用しないで継承を実現する方法 extendsを使用しないで を継承する方法
2. super
superというキーワードは、関数としてもオブジェクトとしても使用できます.この2つの場合、その使い方は全く違います.の第1のケースは、関数として呼び出されると、親の構造関数を表す. は、サブクラスのコンストラクション関数でのみ使用できます. thisより前に を呼び出す上記の状況を満たさないと を一度実行しなければならない.第2の場合、対象とした場合 .一般的な方法では、親のプロトタイプオブジェクトを指します. 静的メソッドでは、親を指します. superは親のプロトタイプオブジェクトを指すため、親インスタンスに定義されたメソッドまたは属性はsuperで呼び出すことができません. 属性が親クラスのプロトタイプオブジェクトに定義されている場合、superは取得できます. thisはサブクラスインスタンスを指すため、superによって属性に値を割り当てると、superはthisであり、値を割り当てる属性はサブクラスインスタンスの属性になります. 6.サブクラスの静的メソッドでsuperによって親クラスを呼び出すメソッドの場合、メソッド内部のthisは現在のサブクラスを指し、 superを対象として使用する場合はsuperのみとなる.xxはsuperを直接印刷するのではなく、 とエラーが発生します.
3.class文法糖実際には について説明しています各オブジェクトにはprotoプロパティがあり、対応するコンストラクション関数のprototypeプロパティを指します.Classは構造関数の構文糖としてprototype属性とproto属性を同時に持つため,2つの継承鎖が同時に存在する. コンストラクタがnewによってインスタンスを生成すると、コンストラクタのprototype属性は、インスタンスのプロトタイプチェーン としてprotoに自動的に変換される.サブクラスのprotoプロパティは、コンストラクション関数の継承を表し、常に親を指します. サブクラスprototypeプロパティのprotoプロパティは、メソッドの継承を表し、常に親クラスのprototypeプロパティを指します.
4.原生構造関数の継承 Array を継承継承Object
など...もっと継承してチェン一峰es 6を参考にします
5. Mixinは、複数のクラス継承を実現する である.チェン一峰の実現
参考博文阮一峰es 6
1.1継承とは
1.2 class継承(extends)
サブクラスextends親
class Point {
}
class ColorPoint extends Point {
}
1.3 constructor
class ColorPoint extends Point {
}
//
class ColorPoint extends Point {
constructor(...args) {
super(...args);
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
// this.color = color;
super(x, y); // constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // toString()
}
}
1.4親と子の関係
class A {
a() {
}
static aa(){
console.log('aa')
}
}
class B extends A {
b() {
}
}
var b = new B()
// , 。
B.aa() // aa
b.aa() // Uncaught TypeError: b.aa is not a function
// B.__proto__ === A
// new , prototype __proto__ ( , __proto__ )
// prototype
// B.prototype === A.prototype; // false
// false? es5 , prototype, ( )
// B.prototype , __proto__ , es6 prototype prototype.__proto__ , , , __proto__ 。
// B.prototype.__proto__ === A.prototype; // true
Es 6の2つの条件は、
B.proto==A//true静的メソッドはB.prototypeを継承する.proto === A.prototype;//trueプロパティメソッド継承
1.5 Object.getPrototypeOf()
Object.getPrototypeOf(B) === A // true
1.6 extendsを使用しないで継承を実現する方法
function A(){
...
}
A.staticA = function(){}
A.prototype.A = function(){}
class B {
constructor() {
A.prototype.constructor.call(this) //
}
b() {
console.log('bar')
}
}
// :
B.__proto__ = A
B.prototype.__proto__ = A.prototype
//
2. super
superというキーワードは、関数としてもオブジェクトとしても使用できます.この2つの場合、その使い方は全く違います.
class A {}
class B extends A {
constructor() {
super(); // super() A.prototype.constructor.call(this)。
}
}
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
let b = new B();
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m // undefined
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
class A {
constructor() {
this.x = 1;
}
static print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
static m() {
super.print();
}
}
B.x = 3;
B.m() // 3
3.class文法糖
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
4.原生構造関数の継承
class MyArray extends Array {
constructor(...args) {
super(...args);
}
}
var arr = new MyArray();
arr[0] = 12;
arr.length // 1
arr.length = 0;
arr[0] // undefined
class NewObj extends Object{
constructor(){
super(...arguments);
}
}
var o = new NewObj({attr: true});
o.attr === true // false
など...もっと継承してチェン一峰es 6を参考にします
5. Mixin
function mix(...mixins) {
class Mix {
constructor() {
for (let mixin of mixins) {
copyProperties(this, new mixin()); //
}
}
}
for (let mixin of mixins) {
copyProperties(Mix, mixin); //
copyProperties(Mix.prototype, mixin.prototype); //
}
return Mix;
}
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if ( key !== 'constructor'
&& key !== 'prototype'
&& key !== 'name'
) {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
参考博文阮一峰es 6