es6 で継承を実装するために使用されるもの
class キーワードと extends キーワードは、es6 で継承を実装するために使用されます。 ES6 ではクラスを宣言するために class キーワードが導入され、extends キーワードを通じてクラス (クラス) を継承できるため、サブクラスが親クラスの属性とメソッドを継承できるようになります。構文は「class 親クラス名 {.. .} クラスのサブクラス名は親クラス名を拡張します {...};"。
このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
es6 では、class キーワードと extends キーワードを使用して継承を実装できます。
ES6 クラスの継承
1. はじめに
クラスは extends を渡すことができますキーワードは継承を実装し、サブクラスが親クラスのプロパティとメソッドを継承できるようにします。これは、プロトタイプ チェーンを変更することによる ES5 の継承の実装よりもはるかに明確で便利です。
//父类 class Point { ... } //子类 class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return this.color + '' + super.toString(); // 调用父类的toString方法 } }
上記のコードでは、コンストラクター メソッドと toString メソッド内に super キーワードが表示されています。ここでの Super は、親クラスの新しいインスタンス オブジェクトを作成するために使用される親クラスのコンストラクターを表します。
ES6 では、サブクラスがコンストラクター メソッドで super() を呼び出す必要があると規定しています。そうしないと、エラーが報告されます。これは、サブクラス独自のこのオブジェクトが、最初に親クラスのコンストラクターを通じて整形され、同じオブジェクトを取得する必要があるためです。親クラスと同じインスタンスのプロパティとメソッドを作成し、サブクラス独自のインスタンスのプロパティとメソッドを追加します。
サブクラスのコンストラクターが super() を呼び出す必要があるのはなぜですか?
これは、ES5 の継承メカニズムでは、最初に独立したサブクラスのインスタンス オブジェクトが作成され、その後、親クラスのメソッドがこのオブジェクトに追加される、つまり「インスタンス ファースト」であるためです。 , "最初に継承"; ES6 の継承メカニズムは、まず親クラスの属性とメソッドを空のオブジェクトに追加し、次にそのオブジェクトをサブクラスのインスタンスとして使用します。つまり、"最初に継承、最後にインスタンス" です。
これは、新しいサブクラス インスタンスが作成されるたびに、親クラスのコンストラクターを 1 回実行する必要があることを意味します。
class Foo { constructor() { console.log(1); } } class Bar extends Foo { constructor() { super(); console.log(2); } } const bar = new Bar(); // 1 2
上記のコードでは、サブクラス Bar が新しいインスタンスを作成するときに、 1 と 2 が出力されます。これは、因子クラスのコンストラクターが super() を呼び出すときに、親クラスのコンストラクターが 1 回実行されます。このキーワードは、サブクラスのコンストラクターで super を呼び出した後にのみ使用できます。使用しない場合は、エラーが報告されます。これは、サブクラス インスタンスの構築では、まず親クラスの継承が完了する必要があり、サブクラス インスタンスが親クラスを継承できるのはスーパー メソッドのみであるためです。
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { this.color = color; super(x, y); this.color = color; } }"
サブクラスがコンストラクター メソッドを定義していない場合、このメソッドはデフォルトで追加され、その中で super が呼び出されます。つまり、明示的に指定されているかどうかに関係なく、すべてのサブクラスにはコンストラクター メソッドがあります。定義済み.
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8} class ColorPoint extends Point { constructor(...args) { super(...args); } } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8}
2. プライベート プロパティとプライベート メソッドの継承
親クラスのすべてのプロパティとメソッドはサブクラスに継承されます。ただし、プライベート プロパティとメソッドは除きます。サブクラスは親クラスのプライベート プロパティを継承できません。また、プライベート プロパティは、サブクラスが定義されているクラス内でのみ使用できます。
class Foo { #p = 1; #m() { console.log('hello'); } } class Bar extends Foo { constructor() { super(); console.log(this.#p); // 报错 this.#m(); // 报错 } }
上記の例では、サブクラス Bar が親クラス Foo のプライベート プロパティまたはプライベート メソッドを呼び出すと、エラーが報告されます。
親クラスがプライベート プロパティの読み取りおよび書き込みメソッドを定義している場合、サブクラスはこれらのメソッドを通じてプライベート プロパティの読み取りおよび書き込みを行うことができます。
class Foo { #p = 1; getP() { return this.#p; } } class Bar extends Foo { constructor() { super(); console.log(this.getP()); // 1 } }
3. 静的プロパティと静的メソッドの継承
親クラスの静的プロパティと静的メソッドは、サブクラスにも継承されます。 。
class A { static hello() { console.log('hello world'); } } class B extends A { } B.hello() // hello world
上記のコードでは、hello()
はクラス A
の静的メソッドであり、B
は A
を継承し、またA
の静的メソッドを継承します。
静的プロパティは浅いコピーによって継承されることに注意してください。継承されたプロパティがプリミティブ データ型の場合、サブクラスで継承された静的プロパティを操作しても親クラスには影響しませんが、継承されたプロパティがオブジェクトの場合は、この場合、サブクラスは、この属性
class C { static foo = 100; } class D extends C { constructor() { super(); D.foo--; } } const d = new D(); C.foo; // 100 D.foo; // 99 class A { static foo = { n: 100 }; } class B extends A { constructor() { super(); B.foo.n--; } } const b = new B(); B.foo.n // 99 A.foo.n // 99
4.Object.getPrototypeOf()
Object を変更するときに親クラスの影響を受けます。 .getPrototypeOf ()
メソッドを使用して、サブクラスから親クラスを取得できます。
class Point { /*...*/ } class ColorPoint extends Point { /*...*/ } Object.getPrototypeOf(ColorPoint) === Point // true
したがって、このメソッドを使用して、クラスが別のクラスを継承しているかどうかを判断できます。
5.super キーワード
super キーワードは関数またはオブジェクトとして使用できます
ある場合には、 、 super が関数として呼び出された場合、それは親クラスのコンストラクターを表します。スーパーを呼び出す機能は、サブクラスの this オブジェクトを形成し、親クラスのインスタンス属性とメソッドをこの this オブジェクトに配置することです。
class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); } } new A(); // A new B(); // B
2 番目のケースでは、super がオブジェクトとして使用される場合、通常のメソッドでは親クラスのプロトタイプ オブジェクトを指しますが、静的メソッドでは親クラスを指します。
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 } } let b = new B();
上記のコードでは、サブクラス B の super.p() が super をオブジェクトとして使用していますが、このとき通常のオブジェクトの super は A.prototype を指しており、 super.p() は In と等価です。 A.prototype.p()。
super は親クラスのプロトタイプ オブジェクトを指すため、親クラスのインスタンスで定義されたメソッドや属性を super 経由で呼び出すことはできません。以下に示すように:
class A { constructor() { this.p = 2; } } class B extends A { get m() { return spuer.p; } } let b = new B(); b.m // undefined
この問題を解決するには、親クラスのプロトタイプ オブジェクトに属性を定義できます。
class A {}; A.prototype.x = 2; class B extends A { constructor() { super(); console.log(super.x); } } let b = new B();
ES6 では、サブクラスの通常のメソッドで次の呼び出しを行うことが規定されています。スーパー メソッドを介した親クラス。メソッド内の this は現在のサブクラス インスタンスを指します
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.print(); } } let b = new B(); b.m(); // 2
上面代码中,super.print()调用的是A.prototype.print(),但是此时方法内部的this指向是子类B的实例,所以输出2。
由于this指向的是子类实例,所有如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性
class A { constructor() { this.x = 1; } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; console.log(super.x); //undefind console.log(this.x); // 3 } }
上面代码中,super.x
赋值为3
,这时等同于对this.x
赋值为3
。而当读取super.x
的时候,读的是A.prototype.x
,所以返回undefined
。
如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。
class Parent { static myMethod(msg) { console.log('static', msg); } myMethod(msg) { console.log('instance', msg); } } class Children extends Parent { static myMethod(msg) { super.myMthod(msg); } myMethod(msg) { super.myMethod(msg); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2
上面代码中,super
在静态方法之中指向父类,在普通方法之中指向父类的原型对象。
另外,在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例
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
在静态方法m中,super.print指向父类的静态方法,到那时this指向的是类B,而不是B的实例。
【推荐学习:javascript高级教程】
以上がes6 で継承を実装するために使用されるものの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









関数の継承では、「基底クラス ポインター」と「派生クラス ポインター」を使用して継承メカニズムを理解します。基底クラス ポインターが派生クラス オブジェクトを指す場合、上方変換が実行され、基底クラスのメンバーのみにアクセスされます。派生クラス ポインターが基本クラス オブジェクトを指す場合、下向きキャストが実行される (安全ではない) ため、注意して使用する必要があります。

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

Go 言語は、高速で効率的なプログラミング言語として、バックエンド開発の分野で広く普及しています。ただし、Go 言語をフロントエンド開発と結びつける人はほとんどいません。実際、フロントエンド開発に Go 言語を使用すると、効率が向上するだけでなく、開発者に新たな視野をもたらすことができます。この記事では、フロントエンド開発に Go 言語を使用する可能性を探り、読者がこの分野をよりよく理解できるように具体的なコード例を示します。従来のフロントエンド開発では、ユーザー インターフェイスの構築に JavaScript、HTML、CSS がよく使用されます。

継承とポリモーフィズムはクラスの結合に影響します。派生クラスは基本クラスに依存するため、継承により結合が増加します。ポリモーフィズムにより、オブジェクトは仮想関数と基本クラス ポインターを通じて一貫した方法でメッセージに応答できるため、結合が軽減されます。ベスト プラクティスには、継承を控えめに使用すること、パブリック インターフェイスを定義すること、基本クラスへのデータ メンバーの追加を回避すること、依存関係の注入を通じてクラスを分離することが含まれます。ポリモーフィズムと依存性注入を使用して銀行口座アプリケーションの結合を軽減する方法を示す実践的な例。

継承エラーのデバッグのヒント: 正しい継承関係を確認します。デバッガーを使用してコードをステップ実行し、変数値を調べます。仮想修飾子を正しく使用してください。隠れた相続によって引き起こされる相続ダイアモンド問題を調べてください。抽象クラスに実装されていない純粋仮想関数がないか確認します。

C++の関数継承を詳しく解説:「is-a」と「has-a」の関係をマスターしよう 関数継承とは?関数の継承は、派生クラスで定義されたメソッドを基本クラスで定義されたメソッドに関連付ける C++ の手法です。これにより、派生クラスが基本クラスのメソッドにアクセスしてオーバーライドできるようになり、基本クラスの機能が拡張されます。 「is-a」および「has-a」関係 関数継承では、「is-a」関係は、派生クラスが基本クラスのサブタイプであること、つまり、派生クラスが基本クラスの特性と動作を「継承」することを意味します。基本クラス。 「has-a」関係は、派生クラスに基本クラス オブジェクトへの参照またはポインターが含まれていること、つまり、派生クラスが基本クラス オブジェクトを「所有」していることを意味します。構文関数継承を実装する方法の構文は次のとおりです: classDerivedClass:pu

Golang とフロントエンド テクノロジーの組み合わせ: Golang がフロントエンド分野でどのような役割を果たしているかを調べるには、具体的なコード例が必要です。インターネットとモバイル アプリケーションの急速な発展に伴い、フロントエンド テクノロジーの重要性がますます高まっています。この分野では、強力なバックエンド プログラミング言語としての Golang も重要な役割を果たします。この記事では、Golang がどのようにフロントエンド テクノロジーと組み合わされるかを検討し、具体的なコード例を通じてフロントエンド分野での可能性を実証します。フロントエンド分野における Golang の役割は、効率的で簡潔かつ学びやすいものとしてです。
