私はJavaとPHPのバックグラウンドから来て、最初はJavaScriptの「クラス」の概念全体に苦労していました。ここで考えるべきことがいくつかあります。
工事
まず、クラスを次のように定義する可能性が高いためです。
Customer = function () {}
Customer.prototype = new Person();
構築中にプロパティとメソッドを定義していると、あらゆる種類のコードの悪夢に遭遇することになります。その理由は、のようなコードではCustomer.prototype = new Person();
、真の継承のためにCustomerコンストラクターでPersonを呼び出す必要があるためです。そうしないと、元のコードが何を設定するかを常に知る必要があります。次の例を見てください。
Person = function (name) {
this.name = name;
this.getName = function () {return this.name}
}
Customer = function (name) {
this.name = name;
}
Customer.prototype = new Person();
次に、Personを更新して、それらが「新規」であるかどうかも設定します。
Person = function (name, isNew) {
this.name = name;
this.isNew = isNew;
this.getName = function () {return (this.isNew ? "New " : "") + this.name; }
}
これで、Personから継承している「クラス」で、フォームに従うようにコンストラクターを更新する必要があります。次のようなことを行うことで、それを回避できます。
Customer = function () {
Person.apply(this, arguments);
}
これにより、新しい「顧客」の範囲内で「個人」が呼び出され、個人の構造について知る必要がなくなります。
スピード
これらのベンチマークを見てください:http: //jsperf.com/inherited-vs-assigned。
基本的に、ここで証明しようとしているのは、これらのオブジェクトをまとめて作成する場合、最適なルートはプロトタイプで作成することです。次のように作成します。
Person = function (name) {
this.name = name;
this.getName = function () {return this.name}
}
オブジェクトを作成するたびに新しい関数が作成されるため、非常に低速です。既存のプロトタイプチェーンを検索するだけではありません。逆に、メソッドが非常に頻繁に呼び出されるオブジェクトが数個しかない場合は、それらをローカルで定義すると、プロトタイプチェーンを検索することで速度が低下します。
共有プロパティ
これはいつも私を取得します。次のようなものがあるとしましょう。
Person = function () {
this.jobs = {};
this.setJob = function (jobTitle, active) {this.jobs[jobTitle] = active; }
}
Employee = function () {}
Employee.prototype = new Person();
var bob = new Employee();
bob.setJob('janitor', true);
var jane = new Employee();
console.log(jane.jobs);
何だと思う?ジェーンは用務員です!冗談抜き!これが理由です。this.jobsをEmployeeのインスタンス化の新しいオブジェクトとして定義しなかったため、「jobs」が検出されてそのまま使用されるまで、プロトタイプチェーンを検索しているだけです。楽しいですよね?
したがって、これはインスタンスを追跡したい場合に便利ですが、ほとんどの場合、非常にイライラすることになります。次の手順を実行することで、これを回避できます。
Employee = function () { Person.apply(this); }
これにより、「Person」は新しい「this.jobs」を作成します。
プライベート変数
JavaScriptには本当に「プライベート」なものはないので、プライベート変数を取得する唯一の方法は、コンストラクターでそれらを作成し、それらに依存するものをコンストラクターで初期化することです。
Person = function () {
var jobs = {};
this.setJob = function (jobTitle, active) {jobs[jobTitle] = active; }
this.getJob = function (jobTitle) { return jobs[jobTitle]; }
}
ただし、これは、継承されたクラスのインスタンス化のたびにそのコンストラクターを呼び出す必要があることも意味します。
提案
http://ejohn.org/blog/simple-javascript-inheritance/
これは非常に基本的なクラスの設定です。それは簡単です。できます。そして、JavaScriptが提供するすべての狂気に対処する必要なしに、90%の時間で必要なことを実行します:)
</rant>