JavaScriptはオブジェクト指向の言語ですが、その継承メカニズムは、設立以来、他の従来のオブジェクト指向言語とは異なりました。これは、プロトタイプベースの継承メカニズムです。ただし、このメカニズムの下では、継承のためのいくつかの異なる実装方法がまだあります。
方法1:古典的継承
いわゆるクラス継承とは、従来のオブジェクト指向言語の継承方法を模倣することを指します。相続財産と相続党はどちらも「クラス」です。コードは次のとおりです。
最初に親クラス(またはスーパークラス)を定義します。
function person(name){this.name = name; } person.prototype.getName = function(){return this.name; };親クラスの人の属性はコンストラクターで定義されています。これにより、サブクラスの名前属性がこの属性を共有するのではなく、サブクラスに個別に属することを保証できます。 getNameメソッドは、このメソッド本体を共有できるようにサブクラスの複数のインスタンスを許可するためにプロトタイプにマウントされ、メモリを保存できるようにします(複数のインスタンスで、新しいインスタンスが発表されるたびに、これらのインスタンスのgetNameメソッドは、独立した空間ではなく同じメモリ空間を参照することを保証します)。
次のように、継承方法を定義します。
function endoct(subclass、superclass){var f = function(){}; f.prototype = superclass.prototype; subclass.prototype = new f(); subclass.prototype.constructor = subclass; subclass.superclass = superclass.prototype; if(superclass.prototype.constructor == object.prototype.constructor){superclass.prototype.constructor = superclass; }}この方法では、最初に新しいクラスFを作成し、そのプロトタイプを親クラスのプロトタイプとし、サブクラスのプロトタイプをクラスFのインスタンスに向けて、親クラスを継承する目的を達成します。同時に、サブクラスのプロトタイプが変更されているため、修正されたプロトタイプのコンストラクター属性はサブクラスを指しているため、コンストラクター機能を備えており、同時にサブクラスはスーパークラス属性をマウントできます。サブクラスは、このプロパティを介して親クラスを呼び出すことができ、サブクラスと親クラスの関係を確立することができます。
次のように、親クラスの人を継承するサブクラスの著者を定義します。
関数著者(name、books){author.superclass.constructor.call(this、name); this.book = books; } extend(著者、人);著者.prototype.getbooks = function(){return this.book; }ここで、親クラスのコンストラクターは、サブクラスのコンストラクターにあるスーパークラス属性を介して呼び出されます。同時に、コールメソッドを使用してメソッドコールのこのポインターを変換するため、サブクラスの著者は親クラスのプロパティを(継承する)(継承)、サブクラスにも独自の属性ブックを持っています。したがって、パラメーターの本は、建設の目的を達成するために、コンストラクターの属性ブックに割り当てられます。拡張機能を使用して、親クラスの人のプロトタイプのプロパティとメソッドを継承します(実際、メソッドのみが継承されます。これは、以前にメソッドをプロトタイプに取り付けただけで、プロパティがコンストラクターに定義されているためです)。同時に、著者には独自の方法GetBooksがあり、対応するプロトタイプにそれを取り付け、相続に基づいてさらに拡大する目的を達成します。
この継承方法は、明らかに、従来のオブジェクト指向言語と同様のタイプ継承です。利点は、従来のオブジェクト指向の概念に慣れているプログラマーにとって簡単であることです。不利な点は、サブクラスにも独自のコンストラクターとプロトタイプがあり、サブクラスと親クラスの属性も完全に分離されているため、プロセスが比較的面倒で、メモリ消費量がわずかに大きいことです。 2つが同じ値であっても、同じメモリを共有することはできません。
方法2:プロトタイプの継承
まず、親クラスを定義します。ここでは、コンストラクターの使用を意図的に模倣して定義しますが、オブジェクトリテラルの形でオブジェクトを直接定義します。これは親クラスです。
var person = {name: 'default name'、getname:function(){return this.name; }};最初の方法と同様に、オブジェクトにはプロパティ名とメソッドgetNameがあります。
次に、次のように、サブクラスのサブクラスの継承を親クラスに実装するためのクローニング方法を定義します。
function clone(obj){function f(){} f.prototype = obj;新しいf()を返します。 }クローンメソッドは、新しいオブジェクトを作成し、オブジェクトのプロトタイプを親クラス、つまりパラメーターOBJに指し、同時にオブジェクトを返します。
最後に、サブクラスは、次のように、クローニング関数を介して親クラスを継承します。
var著者= clone(person); author.book = ['javascript'];著者.showbook = function(){return this.book; }ここでは、サブクラスが定義され、親クラスの人がクローン関数を通じて継承され、属性ブックが拡張され、メソッドショーブックが拡張されます。ここでは、サブクラスには属性名もありますが、親クラスの名前値と同じなので、オーバーライドされていません。違う場合は、使用できます。
author.name = 'new name';このプロパティを上書きして、サブクラスの新しい名前属性値を取得します。
このプロトタイプの継承は、クラスの継承よりもシンプルで自然です。同時に、サブクラスの属性と親クラスの属性値が同じであり、変更できる場合、実際に同じメモリ空間を共有します。たとえば、上記の名前属性は、従来のオブジェクト指向プログラムに慣れているプログラマーにとって理解するのが困難です。 2つが選択される場合、この方法は間違いなく優れています。
JavaScriptは継承を実装するためのプロトタイプベースのアプローチを採用しており、各オブジェクトのプロトタイプは特定のクラスのインスタンス(複数のインスタンスではなく)のインスタンスのみを指すことができるため、複数の継承を実装する方法(つまり、複数のクラスのメソッドと属性が同時にあり、これらのメソッドと属性をインターネットに定義しません)。
JavaScriptの設計パターンでは、ミックスクラスが与えられます。
まず、一般的に使用されるメソッドと属性を保存するドーピングクラスを定義します。これらのメソッドと属性は、拡張を通じて他のクラスに追加できるため、追加されたクラスにはクラスの特定のメソッドと属性があります。複数のドーピングクラスが定義され、同時にクラスに追加された場合、クラスは間接的に「複数継承」を実装します。このアイデアに基づいて、実装は次のとおりです。
要素を支配するクラスの定義:
var mixin = function(){}; mixin.prototype = {serialize:function(){var output = []; for(これのキー){output.push(key+":"+this [key]); } return output.join( '、'); }}ドーピングクラスには、それ自体を横断し、独自の属性と属性値を出力し、コンマで区切られた文字列として返すために使用されるシリアル化方法があります。
次のように、クラスを作成する拡張方法を定義します。
function augment(receiveclass、givingclass){if(arguments [2]){for(var i = 2、len = arguments.length; i <len; i ++){recivingclass.prototype [augmutions [i]] = givingclass.prototype [arguments [i]]; }} else {for(methodname in vishingclass.prototype){if(!receiveclass.prototype [methodname]){recivingclass.prototype [methodname] = givingclass.prototype [methodname]; }}}}この方法には、デフォルトで2つのパラメーターがあります。最初のパラメーターは拡張クラスを受け入れ、2番目のパラメーターはドープクラス(他のクラスの展開に使用)であり、他のパラメーターが存在する場合があります。 2つのパラメーターを超える場合、後続のパラメーターはメソッドまたは属性名であり、拡張クラスがドープクラスの指定された属性またはメソッドを継承したいことを示すために使用されます。それ以外の場合、ドープクラスのすべての属性とメソッドは、デフォルトで継承されます。この関数では、最初のIF分岐は指定された属性とメソッドを継承するために使用され、その他のブランチは、すべての属性とメソッドがデフォルトで継承される場合です。この方法の本質は、要素ドーピングクラスのプロトタイプのプロパティとメソッドを拡張クラスのプロトタイプに拡張(追加)(追加)(追加)、要素ドーピングクラスのプロパティとメソッドを持つようにします。
最後に、拡張方法を使用して複数の継承を実現します
Augment(著者、Mixin); var著者= new Author( 'js'、['JavaScript Design Patterns']); alert(auther.serialize());
これが著者のクラスです。このクラスは、人の親クラスから継承され、代謝されたクラスミックスの方法と特性もあります。必要に応じて、N代謝クラスを定義してクラスを拡張できます。また、定義する他の代謝クラスの特性と方法を継承することができ、複数の継承が実現することもできます。最後に、著者のSerializeメソッドの操作結果は次のとおりです。
このクラスには、人クラス、著者クラス、およびミックスクラスのプロパティと方法の両方があることがわかります。人と混合物の特性と方法はすべて、「継承」によって取得されます。実際、多重継承を実現します。