ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptを深く理解するシリーズ(26):デザインパターンのコンストラクターパターンを詳しく解説_JavaScriptスキル

JavaScriptを深く理解するシリーズ(26):デザインパターンのコンストラクターパターンを詳しく解説_JavaScriptスキル

WBOY
WBOYオリジナル
2016-05-16 16:11:28736ブラウズ

はじめに

コンストラクターについては誰もがよく知っていますが、初心者の場合は、コンストラクターとは何かを理解する必要があります。コンストラクターは、特定の型のオブジェクトを作成するために使用されます。コンストラクターは、使用するオブジェクトを宣言するだけでなく、オブジェクトの最初の作成時にオブジェクトのメンバー値を設定するパラメーターを受け入れることもできます。独自のコンストラクターをカスタマイズし、その中でカスタム タイプ オブジェクトのプロパティまたはメソッドを宣言できます。

基本的な使い方

JavaScript では、通常、インスタンスを実装するためにコンストラクターが使用されます。JavaScript にはクラスの概念がありませんが、特別なコンストラクターが存在します。 new キーワードを使用して定義された関数を呼び出すことにより、新しいオブジェクトを作成することを JavaScript に伝えることができ、新しいオブジェクトのメンバー宣言はすべてコンストラクターで定義されます。コンストラクター内では、 this キーワードは新しく作成されたオブジェクトを参照します。基本的な使い方は以下の通りです:

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

関数 車(モデル、年式、走行距離) {
This.model = モデル;
This.year = year;
This.miles = マイル;
This.output= function () {
return this.model "Gone" this.miles "Kilometers";
};
}

var tom= new Car("Uncle", 2009, 20000);
var dudu= new Car("Dudu", 2010, 5000);

console.log(tom.output());
console.log(dudu.output());

上記の例は非常に単純なコンストラクター パターンですが、いくつか問題があります。まず、継承を使用するのは非常に面倒です。第 2 に、オブジェクトが作成されるたびに、output() が再定義されるのが最善の方法です。インスタンスの数 そうすれば、大量のメモリが節約されます。

この問題を解決するには、次の方法を使用できます:

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

関数 車(モデル、年式、走行距離) {
This.model = モデル;
This.year = year;
This.miles = マイル;
This.output= formatCar;
}

関数 formatCar() {
this.model "Gone" this.miles "Kilometers" を返します;
}


この方法も利用できますが、次のようなより良い方法があります。

コンストラクターとプロトタイプ

JavaScript の関数には、prototype と呼ばれるプロトタイプ属性があります。オブジェクトを作成するためにコンストラクターが呼び出されるとき、コンストラクター プロトタイプのすべての属性は、新しく作成されたオブジェクトで使用できます。これによると、複数の Car オブジェクト インスタンスは同じプロトタイプを共有できます。上記の例のコードを拡張してみましょう:

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

関数 車(モデル、年式、走行距離) {
This.model = モデル;
This.year = year;
This.miles = マイル;
}

/*
注: ここでは、Object.prototype
の代わりに Object.prototype メソッド名を使用します。 主に、定義されたプロトタイプ プロトタイプ オブジェクトの書き換えを避けるために使用されます
*/
Car.prototype.output= function () {
this.model "Gone" this.miles "Kilometers" を返します;
};

var tom = new Car("Uncle", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);

console.log(tom.output());
console.log(dudu.output());


ここで、output() の単一インスタンスは、すべての Car オブジェクト インスタンス間で共有できます。

また: コンストラクターは通常の関数と区別するために大文字で始めることをお勧めします。

新しいものしか使用できませんか?

上記の例ではすべて new を使用して関数 car のオブジェクトを作成しています。これが唯一の方法ですか?実際には他にも方法があり、2 つ挙げます:

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

関数 車(モデル、年式、走行距離) {
This.model = モデル;
This.year = year;
This.miles = マイル;
// 出力内容をカスタマイズします
This.output = function () {
return this.model "Gone" this.miles "Kilometers";
}
}

//方法 1: 関数として呼び出す
Car("Uncle", 2009, 20000) //ウィンドウオブジェクトに追加
console.log(window.output());

//方法 2: 別のオブジェクトのスコープ内で呼び出します
var o = 新しいオブジェクト();
Car.call(o, "ドゥドゥ", 2010, 5000);
console.log(o.output());

このコードのメソッド 1 は少し特殊です。 new を使用して関数を直接呼び出さない場合は、グローバル オブジェクト ウィンドウを参照します。

コードをコピー コードは次のとおりです:
//関数として呼び出す
var tom = Car("おじさん", 2009, 20000);
console.log(tom のタイプ) // "未定義"
; console.log(window.output()); // 「おじさんは2万キロ歩きました」

このとき、オブジェクト tom は未定義なので、 window.output() は正しく結果を出力しますが、 new キーワードを使用すると、そのような問題は発生しません。

コードをコピー コードは次のとおりです:
//新しいキーワードを使用します
var tom = new Car("Uncle", 2009, 20000);
console.log(トムのタイプ) // "オブジェクト"
console.log(tom.output()); // 「おじさんは2万キロ歩きました」

新規強制

上記の例は new を使用しないことの問題を示していますが、コンストラクターに new キーワードを強制的に使用させる方法はありますか? 答えは「はい」です。


コードをコピー コードは次のとおりです:
関数 車(モデル、年式、走行距離) {
If (!(Car のこのインスタンス)) {
新車を返す(モデル、年式、走行距離);
}
This.model = モデル;
This.year = year;
This.miles = マイル;
This.output = function () {
return this.model "Gone" this.miles "Kilometers";
}
}
var tom = new Car("Uncle", 2009, 20000);

var dudu = Car("Dudu", 2010, 5000);

console.log(typeof tom) // "オブジェクト"

console.log(tom.output()); // 「おじさんは2万キロ歩きました」
console.log(typeof dudu); // "オブジェクト"
console.log(dudu.output()); // "ドゥドゥは5000キロ歩きました"

this の instanceof が Car であるかどうかを判断することで、新しい Car を返すか、new キーワードが使用されている場合は (this instanceof Car) が true となり、次のパラメータの割り当てが続行されます。は使用されず、(Car のこのインスタンス) は false で、新しいインスタンスが返されます。

オリジナルラッパー関数

JavaScript には、数値、文字列、ブール値の 3 つの基本的なラッパー関数があります。

両方が使用されることもあります。

コードをコピー コードは次のとおりです:
// 独自のラッパー関数を使用
var s = new String("私の文字列");
var n = 新しい数値(101);
var b = new Boolean(true);

// これはおすすめです
var s = "私の文字列";
var n = 101;
var b = true;

これらのラッパー関数は、数値状態を保持したい場合にのみ使用することをお勧めします。違いについては、次のコードを参照してください。

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

// 元の文字列
vargreet = "こんにちは";
// split() メソッドを使用して
を分割します welcome.split(' ')[0] // "こんにちは"
; // 新しい属性をプリミティブ型に追加するときにエラーは報告されません
挨拶.smile = true;
// この値を取得する方法はありません (その理由については第 18 章 ECMAScript の実装で説明しました)
console.log(typeofgreet.smile) // "未定義"

//元の文字列
vargreet = new String("こんにちは");
// split() メソッドを使用して
を分割します welcome.split(' ')[0] // "こんにちは"
; // ラッパー関数の型に新しい属性を追加してもエラーは発生しません
挨拶.smile = true;
// 新しいプロパティには通常どおりアクセスできます
console.log(typeofgreet.smile) // "boolean"
;

概要

この章ではコンストラクタパターンの使い方や呼び出し方、newキーワードとの違いなどを中心に説明しますので、ご利用の際はご注意ください。

参考: http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript

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