JavaScript は本質的に関数型プログラミング言語であり、Lisp の子孫であると同時に、オブジェクト指向プログラミングの要素を追加し、関数型言語のいくつかの難しい要素を放棄しています。
関数型プログラミング言語がオブジェクト指向プログラミングを実現できることは疑いの余地がありません。Curry メソッドはクラスとオブジェクトのシミュレーションを実現できます。しかし、JavaScript は OOP を実装する別の方法、つまりプロトタイプ継承を提供します。
したがって、オブジェクト指向プログラミングを実装する JavaScript と一般的な関数型プログラミング言語はやはり異なります。
今回はJavaScriptで単一継承と多重継承を実装する方法を紹介します。
プロトタイプを使用した単一継承の実装:
単一継承の実装に役立つ関数を提供する JavaScript ライブラリが多数あります。しかし実際には、JavaScript 自体がプロトタイプ継承のメソッドを提供しています。したがって、特別な実装メソッドを用意する必要はなく、JavaScript コードを使用するだけで単一継承を実現できます。
しかし、JavaScript が提供するプロトタイプ継承メソッドは間違いを犯しやすいので、プロトタイプ継承の実装方法を簡潔かつ明確に説明します。
MyB が MyA クラスを継承すると仮定すると、コードは次のようになります:
function MyA(){
if(MyA.prototype.baseClass!==unknown) {
MyA.prototype.baseClass.call(this);
}
...一般コード
}
function MyB(){
if(MyB.prototype.baseClass!==unknown){
MyB.prototype.baseClass.call(this); 🎜>}
...一般コード
}
MyB.prototype=new MyA();
MyB.prototype.baseClass=MyB。 prototype.constructor;//baseClass を使用して、 // 基本クラスのコンストラクター関数を参照します。
MyB.prototype.constructor=MyB;//サブクラスのコンストラクター属性を復元し、この属性を使用して将来のオブジェクトの型を決定します。
var myA=new MyA();
var myB=new MyB(); 上記の JavaScript ではコードを作成するには、次のコードを各コンストラクターに追加しました。 >
}
このコードはプロトタイプ内でbaseClassメソッドを探し、存在する場合はそれを呼び出します。
プロトタイプ継承の後の実装では、サブクラスの BaseClass 属性を作成しました。その値は基本クラスのコンストラクターです。したがって、私のやり方でコードを書いている限り、サブクラスがインスタンスを構築するときに基本クラスのコンストラクターが実行されることが保証されます。
MyA クラスが Base クラスを継承する場合、次の 3 行のプロトタイプ継承コードを追加するだけです。
MyA.prototype=new Base(); MyA .prototype.baseClass= MyA.prototype.constructor; //baseClass を使用して、 // 基本クラスのコンストラクター関数を参照します。
MyA.prototype.constructor= MyA;//サブクラスのコンストラクター属性を復元し、この属性を使用して将来のオブジェクトの型を決定します。
MyA クラス自体のコードを変更する必要はなく、MyA クラスとそのサブクラス MyB クラスのインスタンスは正しく実行できます。
これらの JavaScript ライブラリによって実装される継承では、Object や Function などの基本クラスの変更が必要となり、競合が発生しやすくなります。また、継承を実装するたびに、コンストラクターが基本クラスのコンストラクターを正しく呼び出せるように、サブクラスのコンストラクターを手動で変更する必要があるメソッドもあります。
JavaScript コードを作成するために上記で提供したメソッドは、これらの問題をうまく解決します。
多重継承を実現するには Mixin (ミックスイン) を使用します
JavaScript 自体は多重継承のメカニズムを提供しませんが、Mixin (ミックスイン) テクニックを使用して多重継承の効果を実現できます。
以下は私が作成した Mixin ヘルパー メソッドです。これはクラスとオブジェクトに属性を動的に追加できます。
1、copyClassPrototypeProperties はクラスのプロトタイプ プロパティをコピーします
/**
* ソース クラスのプロトタイプのすべての属性をターゲット オブジェクトにコピーします。最初のパラメーターは、ターゲット クラスのプロトタイプの属性をオーバーライドするかどうかを示すブール値です。
*/
function copyClassPrototypeProperties(isOverride,receivingClass,givingClass){
if(arguments.length>3){
for(var i=3;i
receivingClass.prototype[arguments[i] ]= giveClass.prototype[arguments[i]];
}
}else if(arguments.length==3){
for(givingClass の変数名。プロトタイプ) {
if(isOverride){
receivingClass.prototype[名前]=givingClass.prototype[名前];
}else{
//オーバーライドしないでください
if(!receivingClass.prototype[name]){
receivingClass.prototype[name]=givingClass.prototype[name]
;
}
}
}
}else{
throw "少なくとも 3 つの引数を指定してください!"
}
}
2、copyObjectProperties はオブジェクトのプロパティをコピーします
/*
* ソース オブジェクトのすべてのプロパティをターゲット オブジェクトにコピーします。パラメータはブール値です。
*/
function copyObjectProperties(isOverride,receivingObject,givingObject){
if(arguments. length>3){
for(var i=3;i
receivingObject[arguments[i]]=givingObject[arguments[i]]; 🎜>
}
}else if(arguments.length==3){
for(givingObject の変数名){
if(isOverride){
receivingObject[name] =givingObject[name];
}else{
//
if(!受信オブジェクト[名前]){
受信オブジェクト[名前]=与えるオブジェクト[名前]
}
}
}
}else{
throw "少なくとも 3 つの引数を指定してください!";
}
}
3, copyProperties はプロパティをオブジェクト /*
* プロパティをターゲットにコピーします。 オブジェクトには、任意の数のプロパティを含めることができ、配列にすることもできます。
*/
function copyProperties(target){
for (var i=1;i
copyArrayProperties(target,arguments[i])
}else{
(arguments[i] の var name){
target[name] =arguments[i][name]
}
}
}
; >/*
* プロパティを配列形式でターゲット オブジェクトにコピーします。ユーザーはこのメソッドを直接呼び出さないでください。
*/
function copyArrayProperties(target,arrayArg){
for(var i=0;i
copyArrayProperties(target,arrayArg[i] );
}else{
for(arrayArg[i] の変数名){
target[name] =arrayArg[i][name]
}
}
}
}
追伸: 現在、UI コンポーネントを含む多くの機能を簡潔なコードで提供する JavaScript ライブラリを作成する予定です。