ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript_javascript スキルでクラスを定義するいくつかの方法の概要

JavaScript_javascript スキルでクラスを定義するいくつかの方法の概要

WBOY
リリース: 2016-05-16 17:05:24
オリジナル
976 人が閲覧しました

オブジェクト指向について考えるとき、クラス、オブジェクト、カプセル化、継承、ポリモーフィズムを考えることができます。 『JavaScript Advanced Programming』(人民郵政出版社、曹立・張新訳、英語名:Professional JavaScript for Web Developers)という書籍に比較的詳しく記載されています。 JavaScript でクラスを定義するさまざまな方法を見てみましょう。

1.ファクトリーメソッド

JavaScript で独自のクラスとオブジェクトを作成する方法をマスターする必要があります。次のコードのように、JavaScript でオブジェクトのプロパティをオブジェクトの作成後に動的に定義できることは誰もが知っています。

コードをコピー コードは次のとおりです:


oCar オブジェクトを使用するのは簡単ですが、複数の Cars の例を作成したいだけです。これを実現するには、関数を使用して上記のコードをカプセル化します:


コードをコピーします コードは次のとおりです:


ちなみに、JavaScript オブジェクトのデフォルトのメンバープロパティはすべて public です。このアプローチはファクトリ アプローチと呼ばれ、特定のタイプのオブジェクトを作成して返すファクトリを作成します。
これは少し興味深いのですが、オブジェクト指向ではオブジェクトの作成によく使用される方法は次のとおりです。
車 car=new Car();

new キーワードの使用は人々の心に深く根付いているため、上記のメソッドを使用して定義すると常にぎこちなく感じられ、呼び出されるたびに新しいプロパティや関数が作成されるため、機能的に実用的ではありません。コンストラクター クラスの正式な定義を見てみましょう。

2.コンストラクター

このメソッドはファクトリー関数に少し似ています。具体的なパフォーマンスは次のとおりです。


コードをコピー コードは次のとおりです。< script type="text/ javascript">
//定義
function Car(color, door) {
this.color = color;
this.doors = door;
this. showColor = function() {
alert(this.color);
};
car1.showColor();
car2.showColor();
< ;/スクリプト>


効果は明ら​​かのようですが、違いがあります。ちょっと面白い感じがします。コンストラクター内でオブジェクトを作成するには this キーワードを使用します。オブジェクトの作成に new 演算子を使用するのは非常に馴染みのあるものです。しかし、問題もあります。新しいオブジェクトが作成されるたびに、関数の作成を含むすべての属性が作成されます。つまり、クラスを定義する目的はメソッドとデータを共有することですが、 car1 オブジェクトと car2 オブジェクトは両方とも独立したプロパティと関数については、少なくともメソッドを共有する必要があります。これがプロトタイプのアプローチの利点です。

3.プロトタイプメソッド

オブジェクトのプロトタイプ属性を使用すると、新しいオブジェクトの作成に依存するプロトタイプを確認できます。方法は次のとおりです。

コードをコピーします コードは次のとおりです。

< script type="text/javascript ">
//定義
function Car() {
};
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car .prototype.drivers = new Array("Tom", "Jerry");
Car.prototype.showColor = function() {
alert(this.color);
}
//呼び出し:
var car1 = new Car();
var car2 = new Car();
car1.showColor();
car2.showColor();
alert(car1.drivers) ;
car1.drivers.push("stephen");
alert(car1.drivers) //結果: トム、ジェリー、スティーブン
alter(car2.drivers); ; //結果: トム、ジェリー、スティーブン

//json を使用してプロトタイプの定義を簡素化できます:

Car.prototype =
{
カラー: "赤"、
ドア: 4、
ドライバー: ["トム"、"ジェリー"、'safdad']、
showColor : function() {
alert(this.color); 次に、プロパティを追加して、オブジェクトのプロトタイプ プロパティを通じて Car オブジェクトのプロパティを定義します。この方法は優れていますが、問題は、Car オブジェクトが Array ポインターを指していることです。一方のオブジェクト car1 が属性オブジェクト (配列 Array) の参照を変更すると、もう一方のオブジェクト car2 も同じ Array 配列を指していることです。属性オブジェクト (配列 Array) の参照を変更することはできません。

同時に、この問題は、プロトタイプが初期化パラメーターを受け取ることができないため、コンストラクターが正常に初期化できないという事実にも現れています。これには、別の解決方法、つまりハイブリッド コンストラクター/プロトタイプ パターンが必要です。

4. 混合コンストラクター/プロトタイプ パターン

コンストラクターとプロトタイプを一緒に使用すると、クラスを定義するのに非常に便利です。

コードをコピー


コードは次のとおりです:


このメソッドは内部の属性を定義し、外部のメソッドをプロトタイプを使用して定義します。 3番目の方法で問題は解決しました。

このメソッドは実際には非常に使いやすいはずですが、Java の構文と比較すると、少し不調和で乱雑なはずです。C の場合、それほど面倒とは感じませんが、C の開発担当者が JavaScript を使用することは一般にほとんどありません。 J2EE 研究開発担当者の皆さん、このアプローチはいつも少しぎこちないものです。実際には、視覚的なカプセル化の効果を達成してこの方法の効果を達成したい場合、それは単にパッケージの視覚効果があまり良くないだけだと個人的には思います。それはもっと面倒です。それがダイナミックプロトタイピング手法です。

5. 動的プロトタイプ

他の言語の使用に慣れている開発者にとって、コンストラクターとプロトタイプを混合したアプローチを使用すると、調和がとれないように感じるかもしれません。結局のところ、ほとんどのオブジェクト指向言語は、クラスを定義するときにプロパティとメソッドを視覚的にカプセル化します。次の C# クラスについて考えてみましょう:

コードをコピーします コードは次のとおりです:

class Car //class
{
public string color = "red";
public int door = 4;
public int mpg = 23;

public Car(string color, int door, int mpg) //constructor
{
this.color = color;
this.doors = door;
this.mpg = mpg;
}
public void showColor() //method
{
Console.WriteLine(this.color);
}
}


C# は非常に優れていますこれは Car クラスのすべてのプロパティとメソッドをパッケージ化しているため、このコードを見ると、オブジェクトの情報を定義していることがわかります。コンストラクターとプロトタイプのハイブリッド アプローチの批判者は、コンストラクターのメモリ内のプロパティやその外部のメソッドを探すのは非論理的であると主張します。したがって、彼らは、より使いやすいコーディング スタイルを提供する動的プロトタイピング アプローチを設計しました。

動的プロトタイプ メソッドの基本的な考え方は、ハイブリッド コンストラクター/プロトタイプ アプローチと同じです。つまり、非機能プロパティはコンストラクター内で定義され、機能プロパティはプロトタイプ プロパティを使用して定義されます。唯一の違いは、オブジェクト メソッドが割り当てられる場所です。以下は、動的プロトタイプ メソッドで書き直された Car クラスです:

コードをコピーします コードは次のとおりです:




このコンストラクターは、typeof Car._initialized が「unknown」に等しいかどうかを確認するまで変更されません。このコード行は、動的プロトタイプ メソッドの最も重要な部分です。この値が未定義の場合、コンストラクターはプロトタイプを使用してオブジェクトのメソッドの定義を続行し、Car._initialized を true に設定します。この値が定義されている場合 (その値が true の場合、typeof の値は Boolean です)、メソッドは作成されません。つまり、このメソッドはフラグ (_initialized) を使用して、プロトタイプにメソッドが割り当てられているかどうかを判断します。このメソッドは 1 回だけ作成され、割り当てられます。従来の OOP 開発者を満足させるために、このコードは他の言語のクラス定義に似ています。

6 工場での混合方法

この方法は通常、前の方法を適用できない場合の回避策です。その目的は、別の種類のオブジェクトの新しいインスタンスを返すだけの偽のコンストラクターを作成することです。このコードはファクトリー関数とよく似ています:

コードをコピーします コードは次のとおりです:

function Car() {
var oTempCar = new Object();
oTempCar.color="red";
oTempCar.doors=4;
oTempCar.mpg=23;
otempcar.showcolor = function(){
;
new 演算子は Car() コンストラクター内で呼び出されるため、2 番目の new 演算子 (コンストラクターの外側にある) は無視されます。コンストラクター内で作成されたオブジェクトは変数 var に戻されます。このアプローチには、オブジェクト メソッドの内部管理に関する従来のアプローチと同じ問題があります。強く推奨: 絶対に必要な場合を除き、この方法の使用は避けてください (第 15 章を参照)。

概要: (どのメソッドを使用するか)
現在最も広く使用されているメソッドは、コンストラクターとプロトタイプの混合メソッドです。さらに、動的プロトタイプのアプローチも一般的であり、機能的にはコンストラクター/プロトタイプのアプローチと同等です。これらの方法のいずれかを使用できます。ただし、コードに問題が発生する可能性があるため、従来のコンストラクターまたはプロトタイプのアプローチを単独で使用しないでください。


コードをコピー


コードは次のとおりです:

}
this.Get = function(carid) {
alert('Get');
}
}

//静的クラス (2:json)


var Car = {
color: 'red',
ドア: 4,
showColor: function() {alert(this.color) } }

Car.showColor();


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート