これらのいずれかを使用することで、他の方法よりも何か利点があるのでしょうか。また、どちらの方法を選択すべきでしょうか。
コンストラクターアプローチ:
var Class = function () {
this.calc = function (a, b) {
return a + b;
};
};
プロトタイプアプローチ:
var Class = function () {};
Class.prototype.calc = function (a, b) {
return a + b;
};
プロトタイプを使用すると、メソッド定義がクラスから分離されるのが気に入りません。また、最初のアプローチではなくこれを使用すべき特別な理由があるかどうかもわかりません。
また、単なる関数定義ではなく、関数リテラルを使用して「クラス」を定義することには何か利点がありますか。
var Class = function () {};
対
function Class () {};
ありがとう!
ベストアンサー1
プロトタイプ チェーンを介して継承するメソッドは、すべてのインスタンスに対して普遍的に変更できます。次に例を示します。
function Class () {}
Class.prototype.calc = function (a, b) {
return a + b;
}
// Create 2 instances:
var ins1 = new Class(),
ins2 = new Class();
// Test the calc method:
console.log(ins1.calc(1,1), ins2.calc(1,1));
// -> 2, 2
// Change the prototype method
Class.prototype.calc = function () {
var args = Array.prototype.slice.apply(arguments),
res = 0, c;
while (c = args.shift())
res += c;
return res;
}
// Test the calc method:
console.log(ins1.calc(1,1,1), ins2.calc(1,1,1));
// -> 3, 3
メソッドの変更が両方のインスタンスに適用されたことに注目してください。これは、ins1
と がins2
同じcalc()
関数を共有しているためです。構築中に作成されたパブリック メソッドでこれを行うには、作成された各インスタンスに新しいメソッドを割り当てる必要がありますが、これは面倒な作業です。これは、ins1
と がそれぞれ個別に作成された独自の関数ins2
を持つためです。calc()
コンストラクター内でメソッドを作成することのもう 1 つの副作用は、パフォーマンスが低下することです。各メソッドは、コンストラクター関数が実行されるたびに作成する必要があります。プロトタイプ チェーン上のメソッドは 1 回作成され、各インスタンスによって「継承」されます。その一方で、パブリック メソッドは「プライベート」変数にアクセスできますが、これは継承されたメソッドでは不可能です。
function Class() {}
vs の質問に関してはvar Class = function () {}
、前者は実行前に現在のスコープの先頭に「引き上げ」られます。後者の場合、変数宣言は引き上げられますが、割り当ては引き上げられません。例:
// Error, fn is called before the function is assigned!
fn();
var fn = function () { alert("test!"); }
// Works as expected: the fn2 declaration is hoisted above the call
fn2();
function fn2() { alert("test!"); }