JavaScriptオブジェクト指向について学ぼう

JavaScriptオブジェクト指向について学ぼう

JavaScript プロトタイプチェーン

すべてのオブジェクトには、別のオブジェクトを指すプロトタイプがあります。他のオブジェクトにも独自のプロトタイプがあります。プロトタイプのプロトタイプで構成されるチェーンは、プロトタイプ チェーンと呼ばれます。

画像-20210924092335152

プロトタイプチェーンの終わり

プロトタイプ チェーンが無限である場合、プロトタイプ チェーンに存在しないプロパティを検索すると、検索が続行され、無限ループが発生します。明らかにそうではありません。では、プロトタイプ チェーンの終わりは何でしょうか?

オブジェクトプロトタイプ

トップレベルのプロトタイプ

コードを見てね〜

// objリテラルの作成方法はnew Object()に似ています
// この場合、obj オブジェクトは Object のインスタンス、つまり、obj.__proto__ === Object.prototype になります。
var obj = {
  名前: "fzb",
};
// では、obj.__proto__ または Oject.prototype の __proto__ とは何でしょうか? 答えは「null」です
console.log(obj.__proto__); // [オブジェクト: null プロトタイプ] {}
console.log(obj.__proto__.__proto__); // ヌル

[Object: null prototype] {}の特別な機能:

1. オブジェクトには prototype プロパティがありますが、 prototype はnullを指しています。つまり、すでに最上位の prototypeになっています。

2. このオブジェクトには他にも多くのメソッドがありますが、列挙できず、表示できません。

Objectオブジェクトのメモリマップを作成する

画像-20210924094822274

上記の例のメモリグラフ

画像-20210924095218150

オブジェクトはすべてのクラスの親クラスです

プロトタイプチェーンの先頭にあるプロトタイプオブジェクトは、オブジェクトのプロトタイプオブジェクトである。

例:

関数 Student(sno, name) {
  this.sno = sno;
  this.name = 名前;
}
2018年1月1日、新しいStuクラスが作成されました。

console.log(stu); // 学生 { sno: 201801、名前: 'fzb' }
console.log(stu.__proto__); // {}
console.log(stu.__proto__.__proto__); // [オブジェクト: null プロトタイプ] {}

console.log(Student.__proto__); // {}
/* ***************コメント内容については後ほど詳しく説明します***************
 * Student.__proto__ = [Object: null prototype] {} ではないのはなぜですか?
 * Student.__proto__ = Function.prototype なので 
 * Function.prototype.__proto__ = Object.prototype = [Object: null prototype] {}
 * ***************注釈の内容については後ほど詳しく説明します***************
 */
console.log(Student.__proto__.__proto__); // [オブジェクト: null プロトタイプ] {}

メモリマップ:

画像-20210924101359674

継承を実現するためのプロトタイプチェーン

継承によりコードの再利用が可能になり、サブクラスで

例:

関数Person() {
  this.name = "fzb";
}

Person.prototype.running = 関数 () {
  console.log(this.name + "実行中~");
};

関数 Student(sno) {
  this.sno = sno;
}
Student.prototype = 新しいPerson();
// プロトタイプオブジェクト全体を書き直した後、コンストラクタを再構成します
Object.defineProperty(Student.prototype, "コンストラクタ", {
  設定可能: true、
  列挙可能: false、
  書き込み可能: true、
  値: 学生、
});
Student.prototype.studying = 関数 () {
  console.log(this.name + "学習中");
};

学生データ
stu.running(); // fzb が実行中です~
stu.studying(); // fzb は勉強中です

メモリマップ:

画像-20210924105330732

欠陥

1> サブクラス オブジェクトを印刷する場合、一部の属性を印刷する必要がありますが、親クラスにあるため、印刷できません。

2> 複数のサブクラス オブジェクトが特定の操作を実行すると、それらは相互に影響を及ぼします。

// 上記の例に少しコードを追加します。
関数Person() {
  this.name = "fzb";
  this.friends = []; // 属性を追加する}
学生のクラスを stu1 に変更します。
stu1.friends.push("zzw");
学生のクラスを stu2 に変更します。
console.log(stu2.friends); // [ 'zzw' ]
// stu2 は stu1 の friends 属性を取得しますが、これは許可されていません

3> パラメータを渡すことができません。親クラスのコンストラクタにいくつかのプロパティが存在します。サブクラスをインスタンス化するときに、初期化パラメータを親クラスに渡すことができません。

コンストラクタによる継承

サブクラスのコンストラクター内で、コンストラクターを呼び出します。親クラスのコンストラクターで this ポインターを変更すると、親クラスによって this に追加されたプロパティが、サブクラスによってインスタンス化されたオブジェクト上に存在するようになります。

関数 Person(名前) {
  this.name = 名前;
  this.friends = [];
}

Person.prototype.running = 関数 () {
  console.log(this.name + "実行中~");
};

関数 Student(sno, name) {
  Person.call(this, name); // コードを追加 this.sno = sno;
}
Student.prototype = 新しいPerson();
// プロトタイプオブジェクト全体を書き直した後、コンストラクタを再構成します
Object.defineProperty(Student.prototype, "コンストラクタ", {
  設定可能: true、
  列挙可能: false、
  書き込み可能: true、
  値: 学生、
});
Student.prototype.studying = 関数 () {
  console.log(this.name + "学習中");
};

学生名を 201801 に設定します。
stu1.friends.push("zzw");
学生名を 201802 とします。
console.log(stu2.friends); // []

この時点で、プロトタイプチェーン継承の 3 つの欠点は解決されます。しかし、新たな欠陥が見つかりました。

欠陥

1> 親クラスのコンストラクタは少なくとも2回実行される

2> サブクラスコンストラクタのプロトタイプオブジェクトは親クラスのインスタンスオブジェクトなので、オブジェクトのプロパティは未定義になります。

画像-20210924111324798

要約する

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • JavaScript オブジェクト指向の実践の詳細説明: カプセル化とオブジェクトのドラッグ
  • JavaScript オブジェクト指向プログラミングの詳細な説明 [クラス作成、インスタンスオブジェクト、コンストラクタ、プロトタイプなど]
  • JavaScriptオブジェクト指向の7つの基本原則の詳細な例
  • JS オブジェクト指向プログラミングの基礎 (パート 3) 継承操作の詳細な例
  • JS オブジェクト指向プログラミングの基礎(第 2 部)カプセル化操作例の詳細説明
  • JS オブジェクト指向プログラミングの基礎 (I) オブジェクトとコンストラクタインスタンスの詳細説明

<<:  キャッシュサーバーを構築するためのMemcached方式

>>:  MySQL の group by と order by を一緒に使用する方法

推薦する

SQL における参照整合性の詳細な説明 (1 対 1、1 対多、多対多)

1. 参照整合性参照整合性とは、主に外部キー制約を使用した複数のテーブル間の設計を指します。複数テ...

Vueを使用して手書き署名機能を実装する

個人的な実装のスクリーンショット:インストール: npm インストール vue-esign --sa...

友達やグループを見つけるためのJavaScriptのLayim

現在、layuiの関係者はlayim友達検索ページの構造とスタイルを提供していません。私は個人的に非...

CocosCreatorゲームにおける魚群アルゴリズムの詳細な説明

序文最近CocosCreatorを学びたいと思ったので、エディターをダウンロードして起動しました。誰...

MySQLデータベースのトランザクションとインデックスの詳細な説明

目次1. 事務:取引の 4 つの主な特徴:同時トランザクションはどのような問題を引き起こしますか? ...

DockerはRedisを起動し、パスワードを設定します

RedisはRedisバージョン5のapline(Alps)イメージを使用します。これは小さくて高速...

JDBC を使用して MySQL を操作するための簡単な分析では、Class.forName("com.mysql.jdbc.Driver") を追加する必要があります。

導入データベースに接続するためにJDBCを使用することに慣れている場合は、データベースに接続するため...

Linux 上の MySQL 5.7 でパスワードを忘れる問題を解決する

1. 問題Linux 上の mysql5.7 のパスワードを忘れました2. 解決策• ステップ 1:...

Linux でソフトウェア パッケージのバージョンをアップグレードする方法の詳細な説明

Linux環境で、特定のソフトウェア(パッケージ)がインストールされているかどうかを確認したい。 r...

CSS3 で King of Glory マッチング人員読み込みページを実装する方法

King of Glory をプレイしたことがある人なら、このページの効果をよくご存知でしょう。なぜ...

Vueルーティングルーターの詳細な説明

目次ルーティングプラグインをモジュール方式で使用するルートの使用宣言型ナビゲーションプログラムによる...

Linux システムで TCP 接続を作成するプロセスの紹介

目次LinuxでTCPを作成する手順サーバクライアントTCP確立プロセスサンプルコードLinuxでT...

MySQL ストアド プロシージャの概念、原則、一般的な使用法の詳細な説明

この記事では、例を使用して、MySQL ストアド プロシージャの概念、原則、および一般的な使用法につ...

JavaScript の Strict モードの詳細な説明

目次導入厳密モードの使用厳格モードの新機能例外を強制的にスローする変数の使用を簡素化する議論を単純化...

mysql explain(分析インデックス)の使い方の詳しい説明

EXPLAIN は、MySQL がインデックスを使用して選択ステートメントを処理し、テーブルを結合す...