検索

JavaScriptの継承システムを徹底解説

Oct 23, 2017 am 09:39 AM
javascriptjs

1. コンストラクターのプロトタイプ属性とプロトタイプオブジェクト

初めて js に触れたとき、私は通常、同じ例に従って関数 new を使用してインスタンスを作成します。 jsの関数はオブジェクトであると聞いただけです。 jsはJavaなどの言語のクラス継承システムを使用せず、プロトタイプオブジェクト(プロトタイプ)を使用して継承システムを実装することがわかります。具体的には、「コンストラクター」を使用してクラス関数を実装します。

まず、プロトタイプの継承における 2 つの重要な概念、プロトタイプ属性とプロトタイプ オブジェクト (インスタンス) について説明します。

js オブジェクト システムに関する限り、作成された各関数 (コンストラクター) には、prototype 属性が含まれます。同時に、コンストラクターを通じて作成された各オブジェクト インスタンスには、_proto_ 属性、prototype 属性、および _proto_ 属性も含まれます。プロトタイプオブジェクトを指します。通常の関数とコンストラクターの唯一の違いは、そのプロトタイプ属性のプロトタイプが意味のある値であるかどうかです。

プロトタイプ属性のプロトタイプが指すプロトタイプは、オブジェクトのインスタンスです。具体的には、以下の図に示すように、コンストラクター Animal() にプロトタイプ オブジェクト B がある場合、コンストラクターによって作成されたすべてのインスタンスを B にコピーする必要があります。つまり、Animal() のインスタンス a1 の _proto_ 属性もプロトタイプ オブジェクト B を指します。したがって、インスタンス a1 は、B のすべてのプロパティ、メソッド、およびその他のプロパティを継承できます。

図 1 JS オブジェクトのインスタンス化の実装

2. 空のオブジェクト

JavaScript では、「空のオブジェクト」はプロトタイプ継承システム全体の基礎であり、すべてのオブジェクトの基礎です。 「空のオブジェクト」を導入する前に、まず「空のオブジェクト (null)」を導入する必要があります。

Empty object null

Null は JavaScript の予約語としての「空のオブジェクト」ではありません。その意味は次のとおりです。

(1) オブジェクト型に属します

(2) オブジェクトは null 値です

オブジェクト型として、for...in を使用して列挙できますが、null 値として、null にはメソッドや属性 (コンストラクター、_proto_、その他の属性を含む) がないため、何も列挙できません。次の例に示すように:


var num=0;
  for(var propertyName in null)
  {
  num++;
  }

Alert(num);//表示される値は0です

最も重要な点は、nullにはプロトタイプがなく、Object()コンストラクター(またはそのサブクラス)、それに対して instanceof 操作を実行すると false が返されます。

2.「空のオブジェクト」

「空のオブジェクト」とは、Object()を通じて構築された標準のオブジェクトインスタンスを指します。例:


obj=new Object();或 obj={};

「空のオブジェクト」は「オブジェクト」のすべての特性を備えているため、toString() や valueof などの事前定義されたプロパティやメソッドにアクセスできます。

3.「空のオブジェクト」とnullの関係

以下の図2の赤線で示したパスのように、「Object.prototype._proto_」を通じてObjectプロトタイプオブジェクトの-proto-attributeを取得すると、 " とすると、 null オブジェクトには属性がないため、 "null" が返されます。つまり、 "Object {}" です

プロトタイプ オブジェクトは、プロトタイプ チェーンの終端です。

図 2 js クラスの継承システム

3. Javascript の継承の実装とプロトタイプチェーンの保守

(1) 継承の実装

最初のセクションでは、JavaScript におけるクラスの継承は変更によって構築されると述べました関数のプロトタイプ属性プロトタイプが実装されます。次のコードに示すように:


function Animal() {
this.name = 'Animal';
};
function Dog() {
};
  Dog.prototype = new Animal();
var d = new Dog();
console.log(d.name);//'Animal'

型の継承は、Animal 型のインスタンスを作成し、それをコンストラクター Dog() のプロトタイプ属性に割り当てることによって実現されます。つまり、Animal は Dog の親クラスです。このようにして、Dog タイプのインスタンス d も、Animal タイプの name 属性にアクセスできます。

(2) プロトタイプチェーン

JSオブジェクト継承システムには、「内部プロトタイプチェーン」と「コンストラクタープロトタイプチェーン」の2つのプロトタイプチェーンがあります。図 3 に示すように、黒い矢印は、パスがコンストラクターのプロトタイプ属性によって維持される「コンストラクター プロトタイプ チェーン」であることを示します。赤い矢印は、パスがオブジェクト インスタンスの _proto_ 属性を通じて維持される「内部プロトタイプ チェーン」であることを示します。

図 3 プロトタイプ チェーン

(3) プロトタイプ チェーンのメンテナンス

図 3 は、コンストラクターが表示されたプロトタイプを通じてプロトタイプ チェーンを構築し、オブジェクト インスタンスも _ proto _ 属性を通じてプロトタイプ チェーンを構築することを示しています。 _ proto _ はアクセスできない内部プロパティであるため (object _ proto _ プロパティの値は Chrome で表示できますが、変更することはできません)、サブクラス (Dog) のインスタンス Dog1 から始まるプロトタイプ チェーン全体にアクセスすることはできません。したがって、図 3 の「内部プロトタイプ チェーン」と「コンストラクター プロトタイプ チェーン」から接続ポイントを見つけて、インスタンスが obj._proto_ にアクセスできない場合に、コンストラクター (2 つのプロトタイプ) を介して内部プロトタイプ チェーンにアクセスできるようにする必要があります。は直列にチェーンされています)。

サブクラスのインスタンスから開始してプロトタイプ チェーン全体にアクセスするには、インスタンスのコンストラクター属性を使用してプロトタイプ チェーンを維持する必要があります。

其实,JavaScript已经为构造器维护了原型属性,根据如下测试代码,当我们自定义一个构造器时,其原型对象是一个Object()类型的实例,但是其原型对象的constructor属性默认总是指向构造器自身,而非指向其父类Object。如图4中构造器实例中蓝色框中的constructor属性,该constructor属性继承自原型对象,因此可以得出一个自定义的构造器产生的实例,其constructor属性默认总是指向该构造器。


function Animal() {
};
var a = new Animal();
console.log(Animal.prototype);//Object(){}
console.log(Animal.prototype.constructor === Animal);//true//true

  

图4

  因此,在_proto_属性不可访问时,可通过a1.constructor.prototype获取实例a1的原型对象。然而,当我们自定义一个构造函数Dog(),并且手动指定其prototype属性值为Animal,即指定Dog的父类为Animal。此时访问d1.constructor值为Animal,而不是Dog;由图5可以看出,Dog的原型对象和dog分别由Animal()和Dog()两个不同的构造器产生,然而他们的constructor属性指向了相同的构造器(Animal),这样就与使用constructor属性串联两种原型链的设想冲突了。

图5

  是构造器出问题还是原型出了问题?图5可以看出,原型继承要求的“复制行为”已经正确实现,能够从子类实例中访问原型对象属性,问题是在给子类构造器Dog()赋予一个原型对象时应该“修正”该原型对象的构造属性值(constructor)。ECMAScript 3标准提供的方法是:保持原型的构造器属性,在子类构造器中初始化其实例对象的构造属性。代码如下: 


function Dog () {
  //初始化constructor属性
   this.constructor=Dog; //或 this.constructor=arguments.callee;
  };
  Dog.prototype = new Animal();//赋予原型对象,实现继承

图6

对constructor属性“修正”后效果如图6所示,在子类构造器Dog中初始化其实例对象的constructor属性后,Dog的实例对象的constructor都指向Dog,而Dog的原型对象的constructor仍然指向父类型构造器Animal。这样就可以实现利用constructor属性串联起原型链,可以从子类实例开始回溯整个原型链。

总结

以上がJavaScriptの継承システムを徹底解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

See all articles

ホット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ヘンタイを無料で生成します。

ホットツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Mac版

SublimeText3 Mac版

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