違いは何ですか
var A = function () {
this.x = function () {
//do something
};
};
と
var A = function () { };
A.prototype.x = function () {
//do something
};
違いは何ですか
var A = function () {
this.x = function () {
//do something
};
};
と
var A = function () { };
A.prototype.x = function () {
//do something
};
例は非常に異なる結果をもたらします。
違いを見る前に、次の点に注意してください。
[[Prototype]]
は、インスタンスのプライベートプロパティを介してインスタンス間でメソッドと値を共有する方法を提供します。myObj.method()
) 、メソッド内のthisはオブジェクトを参照します。これが呼び出しまたはbindの使用によって設定されていない場合、デフォルトでグローバル オブジェクト (ブラウザのウィンドウ) または厳密モードでは未定義のままになります。問題のスニペットは次のとおりです。
var A = function () {
this.x = function () {
//do something
};
};
この場合、変数A
には、関数への参照である値が割り当てられます。その関数が using を使用して呼び出されるとA()
、関数のthisは呼び出しによって設定されないため、デフォルトでグローバル オブジェクトになり、式this.x
は effective になりwindow.x
ます。その結果、右辺の関数式への参照が に代入されwindow.x
ます。
の場合:
var A = function () { };
A.prototype.x = function () {
//do something
};
非常に異なる何かが発生します。最初の行では、変数A
に関数への参照が割り当てられます。JavaScript では、すべての関数オブジェクトにデフォルトでプロトタイププロパティがあるため、 A.prototypeオブジェクトを作成する別のコードはありません。
2 行目では、A.prototype.xに関数への参照が割り当てられています。これにより、存在しない場合はxプロパティが作成され、存在する場合は新しい値が割り当てられます。したがって、オブジェクトのxプロパティが式に含まれる最初の例との違い。
別の例を以下に示します。それは最初のものと似ています(そしておそらくあなたが尋ねようとしていたものです):
var A = new function () {
this.x = function () {
//do something
};
};
この例ではnew
、関数がコンストラクターとして呼び出されるように、関数式の前に演算子が追加されています。で呼び出されるとnew
、関数のthisは、コンストラクターのパブリックプロトタイプを参照するように設定されたプライベート[[Prototype]]
プロパティを持つ新しいオブジェクトを参照するように設定されます。したがって、割り当てステートメントでは、この新しいオブジェクトにプロパティが作成されます。コンストラクターとして呼び出されると、関数はデフォルトでthisオブジェクトを返すため、別のステートメントは必要ありません。x
return this;
Aにxプロパティがあることを確認するには、次のようにします。
console.log(A.x) // function () {
// //do something
// };
コンストラクターを参照する唯一の方法はA.constructorによるものであるため、これはnewの珍しい使用法です。次のようにする方がはるかに一般的です。
var A = function () {
this.x = function () {
//do something
};
};
var a = new A();
同様の結果を達成する別の方法は、すぐに呼び出される関数式を使用することです。
var A = (function () {
this.x = function () {
//do something
};
}());
この場合、A
右辺に関数呼び出しの戻り値を代入します。ここでも、これは呼び出しで設定されていないため、グローバル オブジェクトを参照し、this.x
有効になりwindow.x
ます。関数は何も返さないため、A
の値になりundefined
ます。
これら 2 つのアプローチの違いは、Javascript オブジェクトを JSON との間でシリアル化および逆シリアル化する場合にも現れます。オブジェクトのプロトタイプで定義されたメソッドは、オブジェクトをシリアル化するときにシリアル化されません。これは、たとえば、オブジェクトのメソッドではなくデータ部分だけをシリアル化したい場合に便利です。
var A = function () {
this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance));
// {"objectsOwnProperties":"are serialized"}
関連する質問:
補足: 2 つのアプローチ間で大幅なメモリ節約はないかもしれませんが、プロトタイプを使用してメソッドとプロパティを共有すると、各インスタンスが独自のコピーを持つよりもメモリ使用量が少なくなる可能性があります。
JavaScript は低水準言語ではありません。プロトタイピングやその他の継承パターンを、メモリの割り当て方法を明示的に変更する方法と考えるのはあまり価値がないかもしれません。
他の人が最初のバージョンで言ったように、「this」を使用すると、クラス A のすべてのインスタンスが関数メソッド「x」の独自の独立したコピーを持つことになります。一方、「prototype」を使用すると、クラス A の各インスタンスがメソッド「x」の同じコピーを使用することになります。
この微妙な違いを示すコードを次に示します。
// x is a method assigned to the object using "this"
var A = function () {
this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
this.x = function() { alert( value ); }
};
var a1 = new A();
var a2 = new A();
a1.x(); // Displays 'A'
a2.x(); // Also displays 'A'
a1.updateX('Z');
a1.x(); // Displays 'Z'
a2.x(); // Still displays 'A'
// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };
B.prototype.updateX = function( value ) {
B.prototype.x = function() { alert( value ); }
}
var b1 = new B();
var b2 = new B();
b1.x(); // Displays 'B'
b2.x(); // Also displays 'B'
b1.updateX('Y');
b1.x(); // Displays 'Y'
b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances
他の人が述べたように、いずれかの方法を選択する理由はさまざまです。私のサンプルは、違いを明確に示すためのものです。
次の 2 つの例を見てください。
var A = function() { this.hey = function() { alert('from A') } };
対。
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
ここにいるほとんどの人 (特に評価の高い回答) は、理由を説明せずに、どのように違うのかを説明しようとしました。私はこれは間違っていると思います。まず基本を理解すれば、その違いは明白になります。まずは基本的なことから説明していきましょう...
a) 関数は JavaScript のオブジェクトです。JavaScript のすべてのオブジェクトは、内部プロパティを取得します (つまり、Chrome などのブラウザーを除いて、他のプロパティのようにアクセスすることはできません)。これは、しばしば参照され__proto__
ます (Chrome で実際に入力anyObject.__proto__
して、それが参照するものを確認できます。これはまさにそれです) , プロパティ, それ以上. JavaScript のプロパティ = オブジェクト内の変数.
では、この__proto__
プロパティは何を指しているのでしょうか? 通常は別のオブジェクトです (理由は後で説明します)。プロパティの JavaScript が__proto__
別のオブジェクトを指さないようにする唯一の方法は、 を使用することvar newObj = Object.create(null)
です。これを行っても__proto__
、プロパティはオブジェクトのプロパティとしてまだ存在しますが、別のオブジェクトを指しているのではなく、 を指していnull
ます。
ここで、ほとんどの人が混乱します。
JavaScript で新しい関数を作成すると (これもオブジェクトですよね?)、それが定義された瞬間に、JavaScript はその関数に という新しいプロパティを自動的に作成しますprototype
。それを試してみてください:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype
プロパティとはまったく異なり__proto__
ます。この例では、'A' には 'prototype' と と呼ばれる 2 つのプロパティがあり__proto__
ます。これは人々にとって大きな混乱です。prototype
プロパティはまったく関係がなく、__proto__
別々の値を指す別々のものです。
__proto__
疑問に思われるかもしれません: JavaScript では、すべてのオブジェクトにプロパティが作成されるのはなぜですか? そうですね、一言: delegation。オブジェクトのプロパティを呼び出し、そのオブジェクトにそれがない場合、JavaScript は によって参照されているオブジェクトを探して、それがある__proto__
かどうかを確認します。それがない場合は__proto__
、チェーンが終了するまで、そのオブジェクトのプロパティなどを調べます。したがって、プロトタイプ チェーンという名前が付けられます。もちろん、__proto__
がオブジェクトを指しておらず、代わりに を指している場合null
、幸運にも、JavaScript はそれを認識し、undefined
そのプロパティを返します。
prototype
また、関数を定義するときに、JavaScript が関数に対して呼び出されるプロパティを作成するのはなぜでしょうか? それはあなたをだまそうとするので、クラスベースの言語のように動作することをだまします。
例を続けて、から「オブジェクト」を作成しましょうA
。
var a1 = new A();
これが起こったとき、バックグラウンドで何かが起こっています。a1
新しい空のオブジェクトが割り当てられた通常の変数です。
new
関数呼び出しの前に演算子を使用したという事実A()
は、バックグラウンドで追加の何かを行いました。new
キーワードは、現在参照している新しいオブジェクトを作成しましたが、そのa1
オブジェクトは空です。さらに何が起こっているかは次のとおりです。
各関数定義には、 created?という新しいプロパティが作成されprototype
ます (プロパティとは異なり、アクセスできます)。__proto__
さて、そのプロパティは現在使用されています。
これで、焼きたての空のa1
オブジェクトができあがりました。JavaScript のすべてのオブジェクトには、それが null であるか別のオブジェクトであるかにかかわらず、__proto__
何かを指す (それも持つ) 内部プロパティがあると述べました。オペレーターが行うことは、関数のプロパティを指すようにそのプロパティを設定するa1
ことです。それをもう一度読んでください。それは基本的にこれです:new
__proto__
prototype
a1.__proto__ = A.prototype;
これは空のオブジェクトにすぎないと言いましたA.prototype
( を定義する前に別のものに変更しない限りa1
)。つまり、基本的a1.__proto__
に同じものA.prototype
を指すようになりました。つまり、空のオブジェクトです。どちらも、この行が発生したときに作成された同じオブジェクトを指しています。
A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}
var a1 = new A()
ここで、ステートメントが処理されるときに別のことが起こっています。基本的A()
に実行され、 A が次のような場合:
var A = function() { this.hey = function() { alert('from A') } };
内部のものfunction() { }
はすべて実行されます。this.hey..
行に到達すると、this
に変更され、次のようにa1
なります。
a1.hey = function() { alert('from A') }
this
変更の理由については説明しませんa1
が、これは詳細を学ぶための優れた回答です。
要約するとvar a1 = new A()
、バックグラウンドで 3 つの処理が行われます。
a1
ます。a1 = {}
a1.__proto__
プロパティは、ポイントと同じものをA.prototype
指すように割り当てられます (別の空のオブジェクト {} )
関数は、ステップ 1 で作成された新しい空のオブジェクトに設定さA()
れて実行されています (変更の理由については、上記の回答を参照してください) 。this
this
a1
それでは、別のオブジェクトを作成してみましょう。
var a2 = new A();
手順 1、2、3 が繰り返されます。何か気づきましたか?キーワードはリピートです。ステップ 1:a2
新しい空のオブジェクトになります。ステップ 2: その__proto__
プロパティは同じものA.prototype
を指し、最も重要なことは、ステップ 3: 関数A()
が再度実行されることです。つまり、関数を含むプロパティa2
が取得されます。2 つのSEPARATE 関数を指す名前の 2 つの SEPARATE プロパティがあります。同じことを行う同じ 2 つの異なるオブジェクトに重複した関数があります。おっと... で作成された 1000 個のオブジェクトがある場合、これのメモリへの影響を想像できます。すべての関数宣言は、2 のようなものよりも多くのメモリを消費します。どうすればこれを防ぐことができますか?hey
a1
a2
hey
new A
__proto__
プロパティがすべてのオブジェクトに存在する理由を覚えていますか? そのため、 (存在しない)のyoMan
プロパティを取得すると、そのプロパティが参照され、それがオブジェクトである場合 (ほとんどの場合そうです)、 が含まれているかどうかがチェックされ、含まれていない場合は、そのオブジェクトなどを参照します。そうであれば、そのプロパティ値を取得して表示します。a1
__proto__
yoMan
__proto__
したがって、誰かがこの事実 + を作成するときにa1
、その__proto__
プロパティが同じ (空の) オブジェクトA.prototype
を指しているという事実を使用して、これを行うことにしました。
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
涼しい!を作成するa1
と、再び上記の 3 つの手順がすべて実行されます。手順 3 では、function A()
実行するものが何もないため、何もしません。もしそうなら:
a1.hey
が含まれてa1
いないhey
ことを確認し、その__proto__
プロパティ オブジェクトをチェックして、それが含まれているかどうかを確認します。
このアプローチでは、新しいオブジェクトの作成ごとに関数が複製されるステップ 3 の部分を排除します。a1
個別のプロパティをa2
持つ代わりにhey
、今ではどれもそれを持っていません。それは、あなたは今では自分で理解したと思います。それは良いことです... 理解できれば__proto__
、Function.prototype
これらのような質問はかなり明白になります.
注: 一部の人々は、内部の Prototype プロパティを と呼ばない傾向があります__proto__
。私はこの名前を投稿を通じて使用して、Functional.prototype
プロパティに対して 2 つの異なるものとして明確に区別しました。
ほとんどの場合、それらは本質的に同じですが、オブジェクトごとに個別の関数ではなく、関数のインスタンスが 1 つしかないため、2 番目のバージョンではメモリが節約されます。
最初のフォームを使用する理由は、「プライベート メンバー」にアクセスするためです。例えば:
var A = function () {
var private_var = ...;
this.x = function () {
return private_var;
};
this.setX = function (new_x) {
private_var = new_x;
};
};
JavaScript のスコープ規則により、private_var は this.x に割り当てられた関数で使用できますが、オブジェクトの外部では使用できません。
最初の例は、そのオブジェクトのインターフェースのみを変更します。2 番目の例では、そのクラスのすべてのオブジェクトのインターフェイスを変更します。
this
代わりに使用することの究極の問題prototype
は、メソッドをオーバーライドするときに、基本クラスのコンストラクターがオーバーライドされたメソッドを引き続き参照することです。このことを考慮:
BaseClass = function() {
var text = null;
this.setText = function(value) {
text = value + " BaseClass!";
};
this.getText = function() {
return text;
};
this.setText("Hello"); // This always calls BaseClass.setText()
};
SubClass = function() {
// setText is not overridden yet,
// so the constructor calls the superclass' method
BaseClass.call(this);
// Keeping a reference to the superclass' method
var super_setText = this.setText;
// Overriding
this.setText = function(value) {
super_setText.call(this, "SubClass says: " + value);
};
};
SubClass.prototype = new BaseClass();
var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!
subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
対:
BaseClass = function() {
this.setText("Hello"); // This calls the overridden method
};
BaseClass.prototype.setText = function(value) {
this.text = value + " BaseClass!";
};
BaseClass.prototype.getText = function() {
return this.text;
};
SubClass = function() {
// setText is already overridden, so this works as expected
BaseClass.call(this);
};
SubClass.prototype = new BaseClass();
SubClass.prototype.setText = function(value) {
BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};
var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
これが問題ではないと思われる場合は、プライベート変数なしで生活できるかどうか、およびリークが発生したときにそれを知るのに十分な経験があるかどうかに依存します。また、メソッド定義の後にコンストラクタ ロジックを配置する必要があるのは不便です。
var A = function (param1) {
var privateVar = null; // Private variable
// Calling this.setPrivateVar(param1) here would be an error
this.setPrivateVar = function (value) {
privateVar = value;
console.log("setPrivateVar value set to: " + value);
// param1 is still here, possible memory leak
console.log("setPrivateVar has param1: " + param1);
};
// The constructor logic starts here possibly after
// many lines of code that define methods
this.setPrivateVar(param1); // This is valid
};
var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0
a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0
対:
var A = function (param1) {
this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
this.publicVar = value; // No private variable
};
var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
すべてのオブジェクトは、プロトタイプ オブジェクトにリンクされています。存在しないプロパティにアクセスしようとすると、JavaScript はオブジェクトのプロトタイプ オブジェクトでそのプロパティを検索し、存在する場合はそれを返します。
関数コンストラクターのprototype
プロパティは、 を使用するときにその関数で作成されたすべてのインスタンスのプロトタイプ オブジェクトを参照しますnew
。
x
最初の例では、関数で作成された各インスタンスにプロパティを追加していA
ます。
var A = function () {
this.x = function () {
//do something
};
};
var a = new A(); // constructor function gets executed
// newly created object gets an 'x' property
// which is a function
a.x(); // and can be called like this
2 番目の例では、 で作成されたすべてのインスタンスがA
指すプロトタイプ オブジェクトにプロパティを追加しています。
var A = function () { };
A.prototype.x = function () {
//do something
};
var a = new A(); // constructor function gets executed
// which does nothing in this example
a.x(); // you are trying to access the 'x' property of an instance of 'A'
// which does not exist
// so JavaScript looks for that property in the prototype object
// that was defined using the 'prototype' property of the constructor
結論として、最初の例では、関数のコピーが各インスタンスに割り当てられます。2 番目の例では、関数の 1 つのコピーがすべてのインスタンスで共有されます。
私はこれが死ぬまで答えられたことを知っていますが、速度の違いの実際の例を示したいと思います.
オブジェクトに直接関数:
function ExampleFn() {
this.print = function() {
console.log("Calling print! ");
}
}
var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('x');
//x: 1151.960693359375ms
プロトタイプの機能:
function ExampleFn() {
}
ExampleFn.prototype.print = function() {
console.log("Calling print!");
}
var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('y');
//x: 617.866943359375ms
ここではprint
、Chrome のメソッドを使用して 2,000,000 個の新しいオブジェクトを作成しています。すべてのオブジェクトを配列に格納しています。プロトタイプprint
の装着には、約 1/2 の時間がかかります。
私が JavaScript トレーニング コースで学んだ、より包括的な回答をご紹介しましょう。
ほとんどの回答は、すでに違いについて言及しています。つまり、プロトタイプを作成するとき、関数はすべての(将来の)インスタンスと共有されます。クラスで関数を宣言すると、インスタンスごとにコピーが作成されます。
一般に、正しいか間違っているということはありません。それは好みの問題か、要件に応じた設計上の決定です。ただし、プロトタイプは、この回答の最後でわかるように、オブジェクト指向の方法で開発するために使用される手法です。
質問で2つのパターンを示しました。さらに2つ説明し、関連する場合は違いを説明しようとします. 自由に編集/拡張してください。すべての例で、場所を持ち、移動できる車のオブジェクトに関するものです。
このパターンが現在でも有効かどうかはわかりませんが、存在します。そして、それについて知ることは良いことです。オブジェクトとプロパティをデコレータ関数に渡すだけです。デコレーターは、プロパティとメソッドを含むオブジェクトを返します。
var carlike = function(obj, loc) {
obj.loc = loc;
obj.move = function() {
obj.loc++;
};
return obj;
};
var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();
JavaScript の関数は特殊なオブジェクトです。関数は、呼び出されるだけでなく、他のオブジェクトと同様にプロパティを格納できます。
この場合Car
は、慣れ親しんだ方法で呼び出すことができる関数( objectとも考えます) です。プロパティ(関数を持つオブジェクト)があります。が呼び出されると関数が呼び出され、魔法のように機能し、 内で定義されたメソッドで関数 (オブジェクトと考えてください) を拡張します。methods
move
Car
extend
Car
methods
この例は異なりますが、質問の最初の例に最も近いものです。
var Car = function(loc) {
var obj = {loc: loc};
extend(obj, Car.methods);
return obj;
};
Car.methods = {
move : function() {
this.loc++;
}
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
最初の 2 つのパターンでは、手法を使用して共有メソッドを定義する方法、またはコンストラクターの本体でインラインで定義されたメソッドを使用する方法について説明できます。どちらの場合も、すべてのインスタンスに独自のmove
機能があります。
プロトタイプ委譲による機能共有がプロトタイプパターンのまさに目標であるため、プロトタイプパターンは同じ調査にはあまり適していません。他の人が指摘したように、より良いメモリフットプリントを持つことが期待されています。
ただし、知っておくと興味深い点が 1 つあります。すべてのオブジェクトには、関連付けられた関数 (オブジェクトと考えてください) を指すprototype
便利なプロパティがあります。constructor
最後の3行について:
この例では、それ自体に経由してリンクCar
するprototype
オブジェクトにリンクします。つまり、それ自体です。これにより、特定のオブジェクトを作成したコンストラクター関数を特定できます。constructor
Car
Car.prototype.constructor
Car
amy.constructor
のルックアップが失敗したためCar.prototype
、コンストラクター プロパティを持つ に委譲されます。そしてそうamy.constructor
ですCar
。
さらに、amy
ですinstanceof
Car
。このinstanceof
演算子は、右側のオペランドのプロトタイプ オブジェクト ( ) が左側のオペランドのプロトタイプ ( ) チェーンCar
のどこかにあるかどうかを調べることによって機能します。amy
var Car = function(loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);
一部の開発者は、最初は混乱する可能性があります。以下の例を参照してください。
var Dog = function() {
return {legs: 4, bark: alert};
};
var fido = Dog();
console.log(fido instanceof Dog);
のプロトタイプがのプロトタイプ チェーンのどこにも見つからないため、instanceof
演算子は を返します。は、オブジェクト リテラルで作成される単純なオブジェクトです。つまり、単に に委譲します。false
Dog
fido
fido
Object.prototype
これは実際には単純化された形式のプロトタイプ パターンの別の形式であり、new
コンストラクターを使用するため、たとえば Java でプログラミングする人にとってはよりなじみ深いものです。
これは、実際にはプロトタイプ パターンと同じことを行います。これは、プロトタイプ パターンの単なる構文糖衣です。
ただし、主な違いは、疑似古典的パターンを使用する場合にのみ適用される JavaScript エンジンに実装された最適化があることです。疑似古典的パターンは、プロトタイプ パターンのおそらくより高速なバージョンであると考えてください。両方の例のオブジェクトの関係は同じです。
var Car = function(loc) {
this.loc = loc;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();
最後に、オブジェクト指向プログラミングがどのように行われるかを理解することはそれほど難しくありません。2 つのセクションがあります。
プロトタイプ (チェーン) で共通のプロパティ/メソッドを定義する 1 つのセクション。
そして、オブジェクトを互いに区別する定義を配置する別のセクション (loc
例の variable )。
これにより、JavaScript でスーパークラスやサブクラスなどの概念を適用できるようになります。
自由に追加・編集してください。もう一度完成したら、これをコミュニティ wiki にすることができます。
プロトタイプはクラスのテンプレートです。これは、それの将来のすべてのインスタンスに適用されます。これはオブジェクトの特定のインスタンスです。
@Matthew Crumley が正しいと思います。それらは、構造的にではなくても、機能的には同等です。を使用して作成されたオブジェクトを Firebug を使用して調べると、new
それらが同じであることがわかります。ただし、私の好みは次のとおりです。C#/Java で慣れ親しんだものに似ていると思います。つまり、クラスを定義し、フィールド、コンストラクター、およびメソッドを定義します。
var A = function() {};
A.prototype = {
_instance_var: 0,
initialize: function(v) { this._instance_var = v; },
x: function() { alert(this._instance_var); }
};
編集変数のスコープがプライベートであることを意味するつもりはありませんでした.javascriptでクラスを定義する方法を説明しようとしていました. これを反映するために変数名が変更されました。
他の回答で説明したように、プロトタイプの関数は、インスタンス化ごとに作成される関数ではなく、すべてのインスタンス化で共有されるため、実際にはパフォーマンスに関する考慮事項です。
これを示すためにjsperfをまとめました。クラスのインスタンス化にかかる時間には劇的な違いがありますが、実際には多くのインスタンスを作成している場合にのみ関係があります.