JavaScript プロトタイプとプロトタイプチェーンの深い理解

JavaScript プロトタイプとプロトタイプチェーンの深い理解

1. プロトタイプとは何ですか?

プロトタイプ: 各 JavaScript オブジェクト (null を除く) が作成されると、別のオブジェクトに関連付けられます。このオブジェクトをプロトタイプと呼びます。各オブジェクトはプロトタイプからプロパティを「継承」します。

例えば

var obj = 新しいオブジェクト();

オブジェクトを作成すると、同時にオブジェクトと関連付けられます。図に示すように、関連付けられたオブジェクトは、新しく作成されたオブジェクト obj のプロトタイプです。

2. プロトタイプ

JavaScript では、すべての関数に prototype プロパティがあり、関数のプロトタイプ オブジェクトを指します。 (追記: 関数も実際にはオブジェクトなので、上記 1 の例と矛盾しません)

var obj = 新しいオブジェクト();

いわゆるプロトタイプは、実際には図に示すように、オブジェクトのプロトタイプに関連付けられたプロパティです。

例えば:

 関数 Animal(重量) {
   this.weight = 重量
 }

次の図は、オブジェクトとプロトタイプの関係を示しています。

すべてのオブジェクトはプロトタイプからプロパティを「継承」します

たとえば、cat1 と cagt2 は Animal をインスタンス化します。cat1 と cagt2 には height 属性はありませんが、height の値は 10 として出力できます。実際、cat1 と cagt2 はプロトタイプ Animal.prototype の height 属性を継承します。

 関数 Animal(重量) {
    this.weight = 重量
  }
  動物のプロトタイプの高さ = 10
  var cat1 = 新しい動物()
  var cat2 = 新しい動物()
  コンソール.log('cat1',cat1.height)//10
  コンソール.log('cat2',cat2.height)//10

__プロト__

これは、すべてのオブジェクト (null を除く) が持つ、オブジェクトのプロトタイプを指す __proto__ と呼ばれるプロパティです。

  関数 Animal(重量) {
     this.weight = 重量
  }
  動物のプロトタイプの高さ = 10
  var cat1 = 新しい動物()
  var cat2 = 新しい動物()
 console.log('cat1.__proto__ === Animal.prototype',cat1.__proto__ === Animal.prototype)
 console.log('cat2.__proto__ === Animal.prototype',cat2.__proto__ === Animal.prototype) 

__proto__ とプロトタイプ

  • __proto__はプロトタイプを指すインスタンスの属性です
  • プロトタイプは、プロトタイプを指すオブジェクトまたはコンストラクタのプロパティです。

4. コンストラクター

各プロトタイプには、関連付けられたコンストラクターを指すコンストラクター プロパティがあります。

  関数 Animal(重量) {
     this.weight = 重量
  }
  動物のプロトタイプの高さ = 10
  var cat1 = 新しい動物()
  var cat2 = 新しい動物()
 console.log('cat1.__proto__ === Animal.prototype',cat1.__proto__ === Animal.prototype)
 console.log('Animal===Animal.prototype.constructor',Animal===Animal.prototype.constructor)
// プロトタイプオブジェクトを取得します console.log('Object.getPrototypeOf(cat1) === Animal.prototype',Object.getPrototypeOf(cat1) === Animal.prototype) 

関係図を更新する

cat1.__proto__ === 動物.プロトタイプ

動物 === Animal.prototype.constructor

cat1.constructor === Animal は真ですか?答えは「正しい」です。すべてのオブジェクトは、そのプロトタイプからプロパティを「継承」するからです。cat1 には属性コンストラクタはありませんが、そのプロトタイプ cat1.__proto__ は Animal.prototype を指します。ただし、Animal.prototype のプロトタイプには属性コンストラクタがあるため、cat1 のコンストラクタ属性はプロトタイプのコンストラクタ属性を継承します。ここでプロトタイプチェーンの一部を見てみましょう。

したがって、cat1.constructor === Animal も真である。

5. 例とプロトタイプ

インスタンスの属性を読み取るときに、見つからない場合は、オブジェクトに関連付けられたプロトタイプ内の属性を検索します。それでも見つからない場合は、プロトタイプのプロトタイプを検索し、トップレベルが見つかるまでこれを繰り返します。これはプロトタイプチェーンを形成する

関数 Animal(重量) {
   this.weight = 重量
}
 Animal.prototype.name = '動物'
 var cat1 = 新しい動物()
 cat1.name = '小さな猫'
 コンソールログ('cat1.name',cat1.name)
 cat1.name を削除します。
 コンソールログ('cat1.name',cat1.name) 

ご覧のとおり、属性を削除する前は littleCat でした。属性を削除した後、インスタンスには name 属性がなくなります。name 属性が見つからない場合は、オブジェクト プロトタイプ、つまり cat1.__proto__、つまり Animal.prototype で検索します。Animal.prototype の name 属性の値は animal なので、name 属性を削除した後の値はプロトタイプ animal の属性 name の値になります。

それでは、cat1 のプロトタイプにも name 属性がない場合はどうでしょうか。何が起こるでしょうか?プロトタイプのプロトタイプで探しますか?では、プロトタイプのプロトタイプとは何でしょうか?

6. プロトタイプのプロトタイプ

プロトタイプは、作成時にオブジェクトに関連付けられた別のオブジェクトであると言われています。つまり、プロトタイプもオブジェクトです。プロトタイプはオブジェクトであるため、オブジェクトに関連付けられる必要があります。

プロトタイプオブジェクトが作成されると、オブジェクトにも関連付けられます。

var obj = 新しいオブジェクト();

関係図を見る

では、Object.prototype のプロトタイプはどうでしょうか?

では、Object.prototype.__proto__ とは何でしょうか?

console.log('Object.prototype.__proto__ === null',Object.prototype.__proto__ === null)

結果を見ることができます

つまり、Object.prototype.__proto__ の値は null であり、これは Object.prototype にプロトタイプがないことを意味します。したがって、プロトタイプ チェーンで、属性が最上位のプロトタイプを見つけて属性がない場合、そのような属性は存在しないと考えられます。

7. プロトタイプチェーン

まとめると、プロトタイプのインスタンスを別のオブジェクトに割り当て、そのインスタンスがさらに他のオブジェクトに割り当てられ、実際のコードでオブジェクトに異なる値が割り当てられると、プロトタイプ チェーンが形成されます。これは非常に抽象的かもしれませんが、例を見てみましょう

 関数 Animal(重量) {
     this.weight = 重量
 }
 Animal.prototype.name = '動物'
 var cat1 = 新しい動物()
 var pinkCat = cat1
 console.log('pinkCat.name',pinkCat.name)
 console.log('pinkCat.__proto__ === cat1.__proto__ == Animal.prototype',pinkCat.__proto__ === cat1.__proto__ == Animal.prototype)
 var samllPinkCat = pinkCat
 console.log('samllPinkCat.name',samllPinkCat.name)
 console.log(samllPinkCat.__proto__ == pinkCat.__proto__ === cat1.__proto__ == Animal.prototype)

上記はプロトタイプ チェーンです。レイヤーごとにリンクしてチェーンを形成することを、いわゆるプロトタイプ チェーンといいます。上記では、cat1 が Animal をインスタンス化し、cat1 が pinkCat に割り当てられ、pinkCat が samllPinkCat に割り当てられ、samllPinkCat、pinkCat から cat1、そして最後に Animal へのプロトタイプ チェーンが形成されます。

以上が、JavaScript プロトタイプとプロトタイプ チェーンの詳細な理解への私の紹介です。皆様のお役に立てれば幸いです。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

以下もご興味があるかもしれません:
  • JavaScriptプロトタイプチェーンを理解する
  • JavaScript プロトタイプとプロトタイプチェーンの詳細
  • JavaScript のプロトタイプとプロトタイプチェーンの詳細な説明
  • Javascript プロトタイプとプロトタイプチェーンをご存知ですか?
  • JavaScriptプロトタイプとプロトタイプチェーンの詳細な説明
  • JavaScript のプロトタイプとプロトタイプ チェーンを理解する

<<:  Linux環境にJDK1.8をインストールする

>>:  ウェブページでよく使用される共有コードの完全なリスト(フロントエンドに必須)

推薦する

Vue.js スタイルレイアウト Flutter ビジネス開発共通スキル

シャドウスタイルにおけるフラッターとCSSの対応UIによって指定されたCSSスタイル 幅: 75px...

Linux での MySQL のインストールに関する詳細なチュートリアル

1. MySQLサービスをシャットダウンする# service mysqld stop 2. rpm...

ネイティブJSで禁止すべきメソッドの記述

目次ブロックレベル関数オブジェクトのプロトタイプを直接変更すると呼び出された人発信者評価ブロックレベ...

ラジオボタンとチェックボックス効果の純粋な CSS 実装例

ラジオボタンとチェックボックスラジオボタンとチェックボックスの効果を実現するための純粋な CSSラジ...

Vue3 setup() の高度な使用例の詳細な説明

目次1. オプションAPIと組み合わせAPIの違い2. セットアップを具体的にどのように使用するので...

MySQL の高度な機能 - データ テーブル パーティショニングの概念とメカニズムの詳細な説明

目次パーティション分割メカニズムSELECTクエリINSERT操作DELETE操作更新操作パーティシ...

CSSを使用してTDのINPUTの幅を設定する

最近、C# を使用して Web プログラムを作成していたときに、次のような問題が発生しました。 Te...

MySQL Innodbの主な機能挿入バッファ

目次挿入バッファとは何ですか?挿入バッファのトリガー条件は何ですか?なぜ一意のインデックスにできない...

UbuntuにMySQLをインストールするときにデフォルトのパスワードを変更する詳細な手順

ステップ1: ディレクトリに入ります: cd /etc/mysql、debian.cnfファイルを表...

React ルーティング リンク構成の詳細

1. 属性へのリンク(1)ルーティングパスを配置する(2)指定された形式でオブジェクトを配置する{パ...

WeChatアプレットのサイレントログインとカスタムログイン状態の維持の詳細な説明

目次1. 背景2. サイレントログインとは何ですか? 3. カスタムログイン状態を維持する方法4. ...

MySQL インデックスのパフォーマンス最適化の問題に対する解決策

MySQL によって作成される最適化はインデックスを追加することですが、インデックスを追加しても目的...

発生したブラウザの互換性の問題と解決策(推奨)について

序文:先週の日曜日、先輩から3ページ作るのを手伝って欲しいと頼まれました。データのやり取りなどはなく...

CocosCreator でカメラトラッキングに cc.follow を使用する方法

Cocos Creator バージョン: 2.3.4デモのダウンロード: https://files...

Linux ベースの MySQL マスター スレーブ構成の全プロセスを記録する

mysql マスタースレーブ構成1. 準備ホスト: 192.168.244.128スレーブ: 192...