ホームページ  >  記事  >  ウェブフロントエンド  >  保守可能なオブジェクト指向 JavaScript コードの作成 [翻訳]_js オブジェクト指向

保守可能なオブジェクト指向 JavaScript コードの作成 [翻訳]_js オブジェクト指向

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

保守可能なオブジェクト指向 (OO) JavaScript を作成すると、コストが節約され、人気が高まります。信じられない?おそらく、あなたか他の誰かが戻ってきて、あなたのコードを扱うことになるでしょう。それをできるだけ苦痛のない経験にすれば、時間の節約につながり、それがお金に相当することは誰もが知っています。また、あなたが頭痛の種をなくしてくれた人々の好意も得るでしょう。ただし、保守可能な OO JavaScript の作成に入る前に、OO とは何なのかを簡単に見てみましょう。 OO についてすでに知っている場合は、次のセクションを飛ばしてください。

OO とは何ですか?
オブジェクト指向プログラミングは基本的に、コード内で操作する物理的な現実世界のオブジェクトを表します。オブジェクトを作成するには、まずクラスと呼ばれるものを記述してオブジェクトを定義する必要があります。クラスは、アカウント、従業員、ナビゲーション メニュー、車両、植物、広告、飲み物など、ほとんどすべてのものを表すことができます。その後、操作するオブジェクトを作成するたびに、クラスからオブジェクトをインスタンス化します。言い換えれば、操作するオブジェクトを提供するクラスのインスタンスを作成します。実際、オブジェクトを使用するのに最適な時期は、複数のオブジェクトを扱うときです。それ以外の場合は、単純な関数型プログラムでも同様に機能する可能性があります。オブジェクトは本質的にはデータのコンテナです。したがって、従業員オブジェクトの場合は、従業員番号、名前、開始日、役職、給与、年功序列などを保存できます。オブジェクトには、そのデータを処理する関数 (メソッドと呼ばれる) も含まれています。データの整合性を確保するための仲介手段としてメソッドが使用されます。データを保存する前に変換するためにも使用されます。たとえば、メソッドは任意の形式で日付を受け取り、それを標準化された形式に変換してから保存できます。最後に、クラスは他のクラスから継承することもできます。継承により、さまざまな種類のクラス間でコードを再利用できます。たとえば、銀行口座とビデオ ストアの口座クラスはどちらも、プロフィール情報、口座作成日、支店情報などのフィールドを提供する基本口座クラスから継承できます。その後、それぞれが独自のトランザクションまたはレンタル処理データ構造を定義します。と方法。

警告: JavaScript OO は異なります
前のセクションでは、古典的なオブジェクト指向プログラミングの基本について概説しました。私が古典的と言ったのは、JavaScript がこれらのルールに完全に従っていないからです。代わりに、JavaScript クラスは実際には関数として記述され、継承はプロトタイプです。プロトタイプ継承は基本的に、クラスがクラスから継承するのではなく、プロトタイプ プロパティを使用してオブジェクトから継承することを意味します。

オブジェクトのインスタンス化
JavaScript でのオブジェクトのインスタンス化の例を次に示します:

复制代 代码如下:

// Employee クラスを定義します。
function Employee(num, fname, lname) {
this.getFullName = function () {
return fname " " l 名前;
}
};
// Employee オブジェクトをインスタンス化します
var john = new Employee("4815162342", "John", "Doe");
alert("従業員のフルネームは " john.getFullName());

ここで注意すべき重要な点が 3 つあります:

「class」関数の最初の文字を大文字にしました。この重要な違いにより、これがインスタンス化のためのものであり、通常の関数として呼び出されるものではないことがわかります。
インスタンス化するときに new 演算子を使用します。これを省略すると、単に関数が呼び出され、問題が発生します。
getFullName は this 演算子に割り当てられているため公開されていますが、fname と lname は公開されていません。 Employee 関数によって作成されたクロージャは、getFullName に fname と lname へのアクセスを与え、同時に他のユーザーからは非公開のままにすることができます。
プロトタイプの継承
ここで、JavaScript でのプロトタイプの継承の例を示します。 >
// Human クラスを定義します。 function Human() { this.setName = function (fname, lname) { this.fname = fname; this.lname = lname; } this.getFullName = function () {
return this.fname " " this.lname;

}
}

// Employee クラスを定義します。
function Employee(num) {
this.getNum = function () {
return num;
}
};
// Employee を Human から継承させます
Employee.prototype = new Human();

// Employee オブジェクトをインスタンス化します
var john = new Employee("4815162342");
john.setName("ジョン", "ドウ");
alert(john.getFullName() " の従業員番号は " john.getNum());


今回は、人間に共通のプロパティを含む Human クラスを作成しました。従業員だけでなくすべての人間には名前があるため、fname と lname をそこに移動しました。次に、Human オブジェクトをそのプロトタイプ プロパティに割り当てて、Employee クラスを拡張しました。

継承によるコードの再利用
前の例では、元の Employee クラスを 2 つに分割しました。すべての人間に共通するすべてのプロパティを Human クラスに移動し、Employee に Human を継承させました。そうすることで、Human にレイアウトされたプロパティを Student、Client、Citizen、Visitor などの他のオブジェクトで使用できるようになります。もうお気づきかもしれませんが、これはコードを分割して再利用するための優れた方法です。人間を扱う場合、単一タイプのオブジェクトごとにこれらのプロパティをすべて再作成するのではなく、Human から継承することですでに利用可能なものを使用することができます。さらに、ミドルネームなどのプロパティを追加したい場合は、一度実行すれば、Human から継承するすべてのユーザーがすぐに使用できるようになります。逆に、ミドル ネーム プロパティを 1 つのオブジェクトだけに追加したい場合は、Human に追加する代わりに、そのオブジェクト内で直接実行できます。

パブリックとプライベート
クラスのパブリック変数とプライベート変数について触れたいと思います。オブジェクト内のデータをどのように扱うかに応じて、データをプライベートまたはパブリックにする必要があります。私有地だからといって、人々がアクセスできないわけではありません。最初にいずれかの方法を実行してもらいたいだけかもしれません。

読み取り専用
オブジェクトの作成時に値を 1 回だけ定義したい場合があります。一度作成した値は、誰にも変更されることは望ましくありません。これを行うには、プライベート変数を作成し、インスタンス化時にその値を設定します。

复制代码代码如下:

function Animal(type) {
変数データ = [];
data['type'] = タイプ;
this.getType = function () {
return data['type'];
}
}

varふわふわ = new Animal('犬');
fluffy.getType(); // 'dog' を返します

この例では、Animal クラス内に data というローカル配列を作成します。 Animal オブジェクトがインスタンス化されると、type の値が渡され、データ配列に設定されます。この値はプライベートであるため上書きできません (Animal 関数がそのスコープを定義します)。オブジェクトがインスタンス化された後に型値を読み取る唯一の方法は、明示的に公開した getType メソッドを呼び出すことです。 getType は Animal 内で定義されているため、Animal によって作成されたクロージャによってデータにアクセスできます。このようにして、ユーザーはオブジェクトのタイプを読み取ることはできますが、変更することはできません。

オブジェクトが継承される場合、「読み取り専用」手法は機能しないことに注意することが重要です。継承の実行後にインスタンス化されたすべてのオブジェクトは、これらの読み取り専用変数を共有し、互いの値を上書きします。最も簡単な解決策は、クラス内の読み取り専用変数をパブリック変数に変換することです。ただし、それらを非公開にしなければならない場合は、フィリップがコメントで指摘したテクニックを使用できます。

パブリック
ただし、プロパティの値を自由に読み書きできるようにしたい場合があります。これを行うには、this 演算子を使用してプロパティを公開する必要があります。
复制代代码如下:

function Animal() {
this.mood = '';
}

varふわふわ = new Animal();
fluffy.mood = '幸せ';
ふわふわした気分; // 'happy' を返します

今回、Animal クラスは、自由に書き込んだり読み込んだりできる、mood という名前のプロパティを公開します。前の例の getType 関数と同様に、関数をパブリック プロパティに割り当てることができます。 getType などのプロパティに値を代入しないように注意してください。代入しないと、値とともにプロパティが破壊されてしまいます。

完全にプライベート
最後に、完全にプライベートなローカル変数が必要なシナリオに遭遇するかもしれません。この場合、最初の例と同じパターンを使用し、ユーザーがアクセスするためのパブリック メソッドを作成しないだけで済みます。
复制代代码如下:

function Animal() {
var Secret = "君には決して分からないよ!」
}
varふわふわ = new Animal();

柔軟な API の作成
クラスの作成について説明したので、製品要件の変更に対応するためにクラスの将来を保証する必要があります。プロジェクト作業を行ったり、製品を長期にわたって保守したりしたことがある場合は、要件が変化することをご存知でしょう。それは人生の事実です。そうでないと考えることは、コードが書かれる前にコードが陳腐化する運命にあるということです。突然、タブのコンテンツをアニメーション化したり、Ajax 呼び出しを介してデータを取得したりする必要がある場合があります。未来を正確に予測することは不可能ですが、十分に将来を見据えた柔軟なコードを記述することは可能です。

Saner パラメータ リスト
将来性を考慮して実行できる場所の 1 つは、パラメータ リストを設計するときです。これらはコードを実装する人々の主な連絡先であり、適切に設計されていないと問題が発生する可能性があります。避けたいのは、次のようなパラメーター リストです。
复制代 代码如下:

function人 (従業員 ID、fname、lname、電話番号、ファックス、電子メール、電子メール 2、生年月日) {
};

このクラスは非常に壊れやすいです。コードをリリースした後でミドルネームパラメータを追加したい場合は、順序が重要であるため、リストの最後に追加する必要があります。そのため、作業するのが面倒になります。また、各パラメーターの値がないと作業が困難になります。例:
复制代码代码如下:

var ara = new Person(1234, " Ara"、"ペリバニアン"、"514-555-1234"、null、null、null、"1976-05-17");

パラメータ リストにアプローチするよりクリーンで柔軟な方法は、次のパターンを使用することです:
复制代码 代コード如下:

function Person(employeeId, data) {
};

最初のパラメータは必須であるため存在します。残りは 1 つのオブジェクトにまとめられており、非常に柔軟に操作できます。
复制代代码如下:

var ara = new Person(1234, {
fname: "Ara"、
lname: "Pehlivanian"、
tel: "514-555-1234"、
生年月日: "1976-05-17"
});

このパターンの利点は、読みやすく、柔軟性が高いことです。 FAX、電子メール、電子メール 2 が完全に省略されていることに注目してください。また、オブジェクトは順序に固有ではないため、ミドルネームパラメータの追加は、都合の良い場所に放り込むだけで簡単です:
复制代码 代码如下:

var ara = new Person(1234, {
fname: "Ara",
mname: "Chris",
lname: "Pehlivanian",
電話番号: "514-555-1234"、
生年月日: "1976-05-17"
});

値は次のようにインデックスによってアクセスされるため、クラス内のコードは関係ありません。 >
代码如下:
function Person(employeeId, data) { this.fname = data['fname']; };
data['fname'] が値を返す場合、その値が設定されます。それ以外の場合は、何も壊れず、何も壊れません。

プラグイン可能にする
時間が経つにつれて、製品要件によりクラスに追加の動作が要求される場合があります。しかし、多くの場合、その動作はクラスのコア機能とはまったく関係がありません。また、あるタブのパネルのコンテンツをフェードインしながら別のタブの外部データをフェッチするなど、クラスの 1 つの実装のみに対する要件である可能性もあります。これらの能力を自分のクラスに取り入れたくなるかもしれませんが、そこには属しません。タブ ストリップの役割はタブを管理することです。アニメーションとデータの取得は完全に別のものであり、タブ ストリップのコードの外に置く必要があります。タブ ストリップを将来に備えて、余分な機能をすべて外部に保持する唯一の方法は、ユーザーがコードに動作をプラグインできるようにすることです。言い換えれば、onTabChange、afterTabChange、onShowPanel、afterShowPanel などのイベントを作成することで、ユーザーがコード内の重要な瞬間にフックできるようになります。そうすれば、onShowPanel イベントに簡単にフックして、そのパネルのコンテンツをフェードインするハンドラーを作成でき、誰もが満足できます。 JavaScript ライブラリを使用すると、これを簡単に行うことができますが、自分で解決するのはそれほど難しくありません。 YUI 3 を使用した簡単な例を次に示します。
复制代码 代码如下:

<スクリプト タイプ="text/javascript" src="http://yui.yahooapis.com/combo?3.2.0/build/yui/yui-min.js">



この例には、showPanel メソッドを備えた単純な TabStrip クラスがあります。このメソッドは、onShowPanel と afterShowPanel という 2 つのイベントを起動します。 Y.EventTarget でクラスを拡張することで、これを行う機能が与えられます。それが完了したら、TabStrip オブジェクトをインスタンス化し、それに一連のイベント ハンドラーを割り当てます。これは、実際のクラスをいじらずに、このインスタンスの固有の動作を処理するためのカスタム コードです。

概要

同じページ、Web サイト、または複数のプロジェクトでコードを再利用する予定がある場合は、コードをクラスにパッケージ化して編成することを検討してください。オブジェクト指向 JavaScript は、自然にコードの編成と再利用を改善します。さらに、少し事前に考えておけば、コードを作成した後も長期間使用し続けるのに十分な柔軟性を確保できます。再利用可能で将来性のある JavaScript を作成すると、あなた、あなたのチーム、会社の時間とお金を節約できます。そうすればきっと人気者になれますよ。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。