ホームページ ウェブフロントエンド jsチュートリアル JavaScript オブジェクト指向プロトタイプと継承_js オブジェクト指向

JavaScript オブジェクト指向プロトタイプと継承_js オブジェクト指向

May 16, 2016 pm 05:51 PM
継承する

1. はじめに

この記事は、Microsoft のマスター Scott Allen Prototypes and Inheritance in JavaScript から翻訳されたもので、プロトタイプとは何か、およびプロトタイプによって継承が実現できる理由について詳細な分析と説明を提供します。 . JS OO を理解するのに最適な作品の 1 つです。翻訳が良くない場合は、修正して追加してください。

2. テキスト
JavaScript のオブジェクト指向は他の言語とは異なります。学習する前に、よく知っているオブジェクト指向の概念を忘れるのが最善です。 JS の OO は、より強力で、より議論的で、より柔軟です。

1. クラスとオブジェクト
JS は、伝統的な観点から見たオブジェクト指向言語です。プロパティと動作は 1 つのオブジェクトに結合されます。たとえば、JS の配列は、プロパティとメソッド (プッシュ、リバース、ポップなど) で構成されるオブジェクトです。
コードをコピー コードは次のとおりです。

var myArray = [1, 2];
myArray.push(3);
myArray.reverse();
var length = myArray.length; : これらのメソッド (プッシュはどこから来たのか)一部の静的言語 (JAVA など) では、クラスを使用してオブジェクトの構造を定義します。しかし、JS は「クラス」のない言語 (クラスレス) であり、配列ごとに継承するこれらのメソッドを定義する「Array」というクラスがありません。 JS は動的であるため、必要に応じてオブジェクトにメソッドを自由に追加できます。たとえば、次のコードは、2 次元空間の座標を表すオブジェクトを定義し、その中に add メソッドが含まれています。



コードをコピーy : 5,
add: function(otherPoint)
{
this.x = otherPoint.x;
this.y = otherPoint.y; >};


すべてのポイント オブジェクトに add メソッドが必要です。また、すべてのポイント オブジェクトに add メソッドを追加することなく、すべてのポイント オブジェクトが add メソッドを共有できることを望んでいます。これにはプロトタイプが現れる必要があります。

2. プロトタイプについて
JS のすべてのオブジェクトには暗黙の属性 (状態) があり、これは、上で作成したオブジェクトの配列とポイントと呼ばれます。それぞれのプロトタイプへの参照が含まれています。プロトタイプ参照は暗黙的ですが、ECMAScript が実装したものであり、オブジェクトの _proto_ (Chrome の) プロパティを使用して取得できます。概念的に理解すると、以下の図に示すように、オブジェクトとプロトタイプの関係を考えることができます。



開発者として、_proto_ 属性の代わりに Object.getPrototypeOf 関数を使用して、オブジェクトのプロトタイプ参照を表示します。この記事の執筆時点では、Object.getPrototypeOf 関数は Chrome、Firefox、IE9 でサポートされています。将来的には、さらに多くのブラウザがこの機能をサポートする予定です。この機能はすでに ECMAScript 標準の 1 つです。次のコードを使用して、前に作成した myArray と point オブジェクトが実際に 2 つの異なるプロトタイプ オブジェクトを参照していることを証明できます。

prototype1コードをコピー



コードは次のとおりです。
Object.getPrototypeOf(point) != オブジェクト .getPrototypeOf(myArray);

この記事の残りの部分では、_proto_ も使用します。主に、図や文章では _proto_ の方が直感的であるためです。ただし、これは正規ではないことに注意してください。オブジェクトのプロトタイプを取得するには、Object.getPrototypeOf が推奨されるメソッドです。

2.1 プロトタイプはなぜ特別なのでしょうか?

配列のプッシュ メソッドが myArray のプロトタイプ オブジェクトから来ていることはすでにわかっています。図 2 は、Chrome でのスクリーンショットです。Object.getPrototypeOf メソッドを呼び出して、myArray のプロトタイプ オブジェクトを取得します。

ff852808_img002(en-us,MSDN_10)

図 2

myArray のプロトタイプ オブジェクトには、最初のコードで使用した、push、pop、reverse などの多くのメソッドが含まれていることに注目してください。 。プロトタイプ オブジェクトは、push メソッドの唯一の所有者ですが、このメソッドは myArray を通じてどのように呼び出されるでしょうか?
コードをコピーします コードは次のとおりです。

myArray.push(3); >
Protytype がどのように実装されているかを理解するための最初のステップは、Protytype がまったく特別なものではないことを理解することです。プロトタイプはオブジェクトです。他の JS オブジェクトと同様に、これらのオブジェクトにメソッドとプロパティを追加できます。しかし同時に、Prototype は特別なオブジェクトでもあります。

プロトタイプは次のルールにより特別です。オブジェクトのプッシュ メソッドを呼び出すか、特定のプロパティを読み取りたいことを JS に通知すると、インタプリタ (ランタイム) はまずオブジェクト自体のメソッドまたはプロパティを探します。 。インタプリタがメソッド (または属性) を見つけられない場合、_proto_ 参照に従ってオブジェクトのプロトタイプ内の各メンバーを見つけます。 myArray で Push メソッドを呼び出すと、JS は myArray オブジェクトで Push を見つけませんが、myArray のプロトタイプ オブジェクトで Push を見つけます。つまり、push メソッドが呼び出されます (図 3)。

ff852808_img003(en-us,MSDN_10)図 3


私が説明した動作は、基本的に、オブジェクト自体がそのプロトタイプからすべてのメソッドとプロパティを継承するというものです。この継承関係を JS で実装するためにクラスを使用する必要はありません。つまり、JS オブジェクトはそのプロトタイプからプロパティを継承します。

図 3 は、各配列オブジェクトが独自の状態とメンバーを維持できることも示しています。 myArray の長さプロパティが必要な場合、JS はプロトタイプ内で長さの値を探すことなく、myArray から長さの値を見つけます。この機能を使用してメソッドを「オーバーライド」することができます。つまり、オーバーライドする必要があるメソッド (プッシュなど) を myArray 独自のオブジェクトに入れることができます。これにより、プロトタイプ内のプッシュ メソッドを効果的に隠すことができます。

3. プロトタイプの共有
JS のプロトタイプの本当の魅力は、複数のオブジェクトが同じプロトタイプ オブジェクトを参照できることです。たとえば、2 つの配列を作成します:

コードをコピー コードは次のとおりです:
var myArray = [ 1, 2];var yourArray = [4, 5, 6];

2 つの配列は同じプロトタイプ オブジェクトを共有し、次のコードは true を返します

コードをコピー コードは次のとおりです:
Object.getPrototypeOf(myArray) === Object.getPrototypeOf(yourArray) ;


2 つの配列でプッシュ メソッドを呼び出すと、JS は共通のプロトタイプでプッシュ メソッドを呼び出します。

ff852808_img004(en-us,MSDN_10)

プロトタイプ オブジェクトは、JS でこの継承機能を提供し、メソッドの実装を共有することもできます。プロトタイプも連鎖します。言い換えれば、プロトタイプはオブジェクトであり、プロトタイプ オブジェクトは別のプロトタイプ オブジェクトへの参照を持つこともできます。図 2 からわかるように、プロトタイプの _proto_ 属性は null 以外の値であり、JS がプッシュ メソッドなどのメンバー変数を探し始めると、これらの各プロトタイプ参照をチェックします。このオブジェクトが見つかるか、チェーンの終端に到達するまで。このチェーン方式により、JS での継承と共有の柔軟性が高まります。

次に、カスタム オブジェクトのプロトタイプ参照を設定するにはどうすればよいでしょうか?たとえば、前に作成したオブジェクト ポイントの場合、すべてのポイント オブジェクトがそれを継承できるように、プロトタイプ オブジェクトに add メソッドを追加するにはどうすればよいでしょうか。この質問に答える前に、まず JS の関数について理解しましょう。

4. 関数について
JS では関数もオブジェクトです。関数には JS の重要な機能が多数あり、この記事ではすべてをリストすることはできません。ただし、関数を変数に代入したり、関数を別の関数のパラメーターとして使用したりすることは、今日の JS プログラミングにおける非常に基本的な方法です。

注意する必要があるのは、関数はオブジェクトであるため、メソッド、プロパティ、プロトタイプ オブジェクトへの参照を持っているということです。次のコードの意味について説明します:
コードをコピー コードは次のとおりです:

// これは true を返します:
typeof (Array) === "function"
// そして次も同様です:
Object.getPrototypeOf(Array) === Object.getPrototypeOf(function () { })
// そしてこれも:
Array.prototype != null

コードの最初の行は、Array が JS の関数であることを証明しています。後で、Array 関数を呼び出して新しい配列オブジェクトを作成する方法を説明します。

コードの 2 行目は、すべての配列オブジェクトがプロトタイプを共有していることを前に見たのと同様に、Array オブジェクトと関数オブジェクトが同じプロトタイプを参照していることを証明しています。

最後の行は、Array 関数がプロトタイプ属性を持つことを証明しています。このプロトタイプ属性を _proto_ 属性と混同しないでください。使用目的や指す対象が異なります。
コードをコピー コードは次のとおりです:

// true
Array.prototype == Object .getPrototypeOf(myArray)
// これも true
Array.prototype == Object.getPrototypeOf(yourArray);

新しい知識を使用して前の図を再描画します。 🎜 >

ff852808_img005(en-us,MSDN_10)

図 5

次に、配列オブジェクトを作成する必要があります。メソッドの 1 つは次のとおりです:


コードをコピーします コードは次のとおりです:
//新しい空のオブジェクトを作成します
var o = {};
// 配列オブジェクトとして同じプロトタイプを継承します
o.__proto__ = Array.prototype
// これで、任意のオブジェクトを呼び出すことができます。配列メソッドの ...
o.push(3);
上記のコードは適切に見えますが、問題は、すべての JS 環境がオブジェクトの _proto_ 属性をサポートしているわけではないことです。幸いなことに、JS には、新しいオブジェクトを作成し、オブジェクトの _proto_ プロパティを設定するための標準の組み込みメカニズムが備わっています。これが「new」演算子です。
コードをコピーします コードは次のとおりです。

var o = new Array(); 🎜>o .push(3);

JS では、「new」演算子には 3 つの重要なタスクがあります。まず、新しい空のオブジェクトを作成します。次に、この新しいオブジェクトの _proto_ 属性が、呼び出し側関数のプロトタイプ属性を指すように設定されます。最後に、呼び出し関数が実行され、「this」ポインタが新しいオブジェクトを指します。上記の 2 行のコードを展開すると、次のコードが得られます。

コードをコピー コードは次のとおりです。
var o = {};
o.__proto__ = Array.call(o);


関数の「call」メソッドを使用すると、関数を呼び出して、関数内の「this」が渡された新しいオブジェクトを指すように指定できます。もちろん、オブジェクトの継承を実現するために、上記のメソッドを通じて独自のオブジェクトを作成することもできます。この関数は、私たちがよく知っているコンストラクターです。
5. コンストラクター
コンストラクターは、2 つの一意の識別子を持つ共通の JS 関数オブジェクトです:

1. 最初の文字は大文字です (識別しやすい)。

2. 新しい演算子接続を使用して新しいオブジェクトを構築します。

配列はコンストラクターです。配列関数は new に接続され、最初の文字は大文字になります。 JS の Array 関数は組み込みですが、誰でも独自のコンストラクターを作成できます。実際、いよいよ point オブジェクトのコンストラクターを作成します。




コードをコピー コードは次のとおりです。 var Point = function (x , y) {
this.x = x;
this.y = y;
this.add = function (otherPoint) {
this.x =
this. y = otherPoint .y;
}
}
var p1 = new Point(3, 4)
var p2 = new Point(8, 6); );


上記のコードでは、new 演算子と Point 関数を使用してポイント オブジェクトを構築します。メモリ内では、図 6 に示すような最終結果を考えることができます。



図 6 ff852808_img006(en-us,MSDN_10)問題は、add メソッドがすべてのポイント オブジェクトに存在することです。プロトタイプについての知識を考慮すると、(add メソッドのコードをすべてのオブジェクトにコピーする必要がなく) Point.prototype に add メソッドを追加する方が良い選択になります。この目的を達成するには、Point.prototype オブジェクトにいくつかの変更を加える必要があります。





コードをコピー
コードは次のとおりです。 var Point = function (x , y) { this.x = x;
this.y = y;
Point.prototype.add = function (otherPoint) {
this.x = otherPoint.x ;
this.y = otherPoint.y;
}
var p1 = 新しいポイント(3, 4)
var p2 = 新しいポイント(8, 6); (p2) ;


わかりました!プロトタイプを使ってJSで継承を実装しました!




6. 概要
この記事がプロトタイプの霧を晴らすのに役立つことを願っています。もちろん、これは強力で柔軟なプロトタイプの単なる紹介にすぎません。読者がプロトタイプについて自分で調べてさらに発見できることを願っています。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

C++関数継承の詳しい解説:継承で「基底クラスポインタ」と「派生クラスポインタ」を使うには? C++関数継承の詳しい解説:継承で「基底クラスポインタ」と「派生クラスポインタ」を使うには? May 01, 2024 pm 10:27 PM

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

継承とポリモーフィズムは C++ のクラス結合にどのような影響を与えますか? 継承とポリモーフィズムは C++ のクラス結合にどのような影響を与えますか? Jun 05, 2024 pm 02:33 PM

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

PHP エラーの解決: 親クラスの継承時に問題が発生しました PHP エラーの解決: 親クラスの継承時に問題が発生しました Aug 17, 2023 pm 01:33 PM

PHP エラーの解決: 親クラスの継承時に発生する問題 PHP では、継承はオブジェクト指向プログラミングの重要な機能です。継承により、元のコードを変更することなく、既存のコードを再利用し、拡張および改善できます。継承は開発で広く使用されていますが、親クラスから継承するときにエラーの問題が発生することがあります。この記事では、親クラスから継承するときに発生する一般的な問題の解決に焦点を当て、対応するコード例を示します。質問 1: 親クラスが見つかりません。親クラスの継承処理中に、システムが親クラスを見つからない場合、

C++ 関数の継承の詳細な説明: 継承のエラーをデバッグするには? C++ 関数の継承の詳細な説明: 継承のエラーをデバッグするには? May 02, 2024 am 09:54 AM

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

継承した Java プログラムを使用して定期預金 (FD) および定期預金 (RD) の利息を計算します 継承した Java プログラムを使用して定期預金 (FD) および定期預金 (RD) の利息を計算します Aug 20, 2023 pm 10:49 PM

継承は、あるクラスのプロパティと動作に別のクラスからアクセスできるようにする概念です。メソッドやメンバ変数を継承するクラスをスーパークラスまたは親クラスと呼び、メソッドやメンバ変数を継承するクラスをサブクラスまたはサブクラスと呼びます。 Javaでは、クラスを継承するために「extends」キーワードを使用します。この記事では、相続を利用して定期預金や定期預金の利息を計算する Java プログラムについて説明します。まず、ローカル マシンの IDE でこれら 4 つの Java ファイル Acnt.java を作成します。このファイルには、金利や金額などの口座詳細を保存するために使用される抽象クラス「Acnt」が含まれます。また、計算用のパラメータ「amnt」を持つ抽象メソッド「calcIntrst」も含まれます。

PHPの多重継承 PHPの多重継承 Aug 23, 2023 pm 05:53 PM

継承: 継承は、クラスが他のクラスからプロパティと動作を継承できるようにするオブジェクト指向プログラミング (OOP) の基本概念です。これは、既存のクラスに基づいて新しいクラスを作成し、コードの再利用を促進し、クラス間の階層関係を確立するためのメカニズムです。継承は、「親と子」または「スーパークラスと子」の関係の概念に基づいています。継承するクラスをスーパークラスまたは基底クラスと呼び、スーパークラスを継承するクラスをサブクラスまたは派生クラスと呼びます。サブクラスは、スーパークラスのすべてのプロパティ (変数) とメソッド (関数) を継承し、独自の一意のプロパティとメソッドを追加したり、継承されたプロパティとメソッドをオーバーライドしたりすることもできます。クラスが他のクラスからプロパティと動作を継承できるようにします。それは促進します

PHP でポリモーフィズムと継承を使用してデータ型を処理する方法 PHP でポリモーフィズムと継承を使用してデータ型を処理する方法 Jul 15, 2023 pm 07:41 PM

PHP でデータ型を処理するためにポリモーフィズムと継承を使用する方法 はじめに: PHP では、ポリモーフィズムと継承は 2 つの重要なオブジェクト指向プログラミング (OOP) 概念です。ポリモーフィズムと継承を使用することで、さまざまなデータ型をより柔軟に処理できます。この記事では、ポリモーフィズムと継承を使用して PHP でデータ型を処理する方法を紹介し、コード例を通じてその実際の応用例を示します。 1. 継承の基本概念 継承はオブジェクト指向プログラミングにおける重要な概念であり、親クラスのプロパティとメソッドを継承できるクラスを作成できます。

PHP のパッケージング技術とアプリケーション PHP のパッケージング技術とアプリケーション Oct 12, 2023 pm 01:43 PM

PHP のカプセル化テクノロジとアプリケーションのカプセル化は、オブジェクト指向プログラミングにおける重要な概念であり、外部プログラムに統一されたアクセス インターフェイスを提供するために、データとデータに対する操作を一緒にカプセル化することを指します。 PHP では、アクセス制御修飾子とクラス定義を通じてカプセル化を実現できます。この記事では、PHP のカプセル化テクノロジとそのアプリケーション シナリオを紹介し、いくつかの具体的なコード例を示します。 1. カプセル化されたアクセス制御修飾子 PHP では、カプセル化は主にアクセス制御修飾子によって実現されます。 PHP には 3 つのアクセス制御修飾子が用意されています。

See all articles