違いは何ですか
var A = function () {
this.x = function () {
//do something
};
};
そして
var A = function () { };
A.prototype.x = function () {
//do something
};
a1.x !== a2.x
; プロトタイプ:a1.x === a2.x
違いは何ですか
var A = function () {
this.x = function () {
//do something
};
};
そして
var A = function () { };
A.prototype.x = function () {
//do something
};
a1.x !== a2.x
; プロトタイプ:a1.x === a2.x
回答:
例には非常に異なる結果があります。
違いを見る前に、次のことに注意してください。
[[Prototype]]
プロパティを介してインスタンス間でメソッドと値を共有する方法を提供します。myObj.method()
、その後)このメソッド参照内のオブジェクト。これが呼び出しまたはbindの使用によって設定されていない場合、デフォルトではグローバルオブジェクト(ブラウザのウィンドウ)または厳密モードでは未定義のままになります。だからここに問題のスニペットがあります:
var A = function () {
this.x = function () {
//do something
};
};
この場合、変数にA
は関数への参照である値が割り当てられます。その関数がを使用して呼び出される場合A()
、関数のthisは呼び出しによって設定されないため、デフォルトでグローバルオブジェクトになり、式this.x
は有効になり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]]
プロパティがコンストラクターのパブリックプロトタイプを参照するように設定された新しいオブジェクトを参照するように設定されます。したがって、割り当てステートメントでは、x
この新しいオブジェクトにプロパティが作成されます。コンストラクターとして呼び出されると、関数はデフォルトでthisオブジェクトを返すため、個別の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は低水準言語ではありません。メモリの割り当て方法を明示的に変更する方法として、プロトタイピングや他の継承パターンを考えることはあまり価値がないかもしれません。
null
)がありますが、これはprototype
プロパティとは非常に異なります。これは、関数上にあり、すべてのインスタンスのプロトタイプがで構築されるときに設定されるプロパティnew
です。これは本当に87 upvotes :-(だと信じてすることはできません
"The language is functional"
これが機能的意味であると確信していますか?
A
の半分は関数として使用した場合に何が起こるかに関するものであり、残りの半分は不明瞭で正統でない方法についてです簡単なもの。
他の人が最初のバージョンを言ったように、「this」を使用すると、クラスAのすべてのインスタンスが関数メソッド「x」の独自の独立したコピーを持つことになります。一方、「プロトタイプ」を使用すると、クラス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
他の人が述べたように、いずれかの方法を選択するさまざまな理由があります。私のサンプルは、違いを明確に示すためのものです。
this
は、メソッドの所有者であるオブジェクトへの依存がないことを意味します。つまり、メソッドにはその所有者であるオブジェクトがありません。この場合this
、例のクラスAに示すように、オブジェクトがあります。
次の2つの例を見てください。
var A = function() { this.hey = function() { alert('from A') } };
対
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
ここにいるほとんどの人々(特にトップ評価の回答)は、なぜかを説明することなく、自分たちの違いを説明しようとしました。これは間違っていると思います。最初に基礎を理解すれば、違いが明らかになります。最初に基礎を説明してみましょう...
a)関数はJavaScriptのオブジェクトです。JavaScriptのすべてのオブジェクトは内部プロパティを取得します(つまり、他のプロパティのようにアクセスすることはできません。ただし、Chromeなどのブラウザを除く)。これは、(Chromeに__proto__
実際に入力anyObject.__proto__
して、参照先を確認することができます。これだけです) 、プロパティ、それ以上。JavaScriptのプロパティ=オブジェクト内の変数、それ以上。変数は何をするのでしょうか。
この__proto__
プロパティは何を指しているのでしょうか?まあ、通常は別のオブジェクトです(理由は後で説明します)。__proto__
プロパティのJavaScript が別のオブジェクトをポイントしないようにする唯一の方法は、を使用することvar newObj = Object.create(null)
です。これを行っても、__proto__
プロパティSTILLはオブジェクトのプロパティとして存在し、別のオブジェクトを指すのではなく、を指すだけnull
です。
ここでほとんどの人が混乱します:
JavaScriptで新しい関数を作成すると(これもオブジェクトです。覚えていますか?)、関数が定義されると、JavaScriptはその関数にという新しいプロパティを自動的に作成しますprototype
。それを試してみてください:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype
__proto__
プロパティとはまったく異なります。この例では、「A」に「プロトタイプ」と呼ばれる2つのプロパティがあり__proto__
ます。これは人々にとって大きな混乱です。prototype
そして、__proto__
プロパティは、彼らが別の値を指している別のものだ、決して関連しています。
疑問に思われるかもしれません:なぜJavaScriptは__proto__
すべてのオブジェクトにプロパティを作成しているのですか?さて、一言:委任。オブジェクトのプロパティを呼び出し、そのオブジェクトにプロパティがない場合、JavaScriptはによって参照され__proto__
ているオブジェクトを探して、それが含まれているかどうかを確認します。ない場合は、そのオブジェクトの__proto__
プロパティなどを調べ、チェーンが終了するまで続けます。したがって、名前のプロトタイプチェーン。もちろん、__proto__
がオブジェクトをポイントせず、代わりにをポイントしているnull
場合、幸運なことに、JavaScriptはそれを認識しundefined
、プロパティに戻ります。
またprototype
、関数を定義するときにJavaScriptが関数に対して呼び出されるプロパティを作成するのはなぜでしょうか。それはあなたをだまそうとするので、はい、それはクラスベースの言語のように機能することをあなたをだます。
例を先に進めて、以下から「オブジェクト」を作成しますA
。
var a1 = new A();
このことが起こったとき、バックグラウンドで何かが起こっています。a1
新しい空のオブジェクトが割り当てられた通常の変数です。
new
関数を呼び出す前に演算子を使用したという事実によりA()
、バックグラウンドで追加の処理が行われました。new
キーワードは、今の参照を新しいオブジェクトを作成a1
し、そのオブジェクトは空です。さらに、次のことが起こります。
それぞれの関数定義で、呼び出された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
、(別の空のオブジェクト{})を指すのと同じものを指すように割り当てられます
関数A()
はthis
、ステップ1で作成された新しい空のオブジェクトに設定して実行されています(なぜにthis
変更されるかについて上記で参照した回答を読んでくださいa1
)
次に、別のオブジェクトを作成してみましょう。
var a2 = new A();
ステップ1、2、3が繰り返されます。何か気づきましたか?キーワードは繰り返しです。ステップ1:a2
新しい空のオブジェクトになります。ステップ2:その__proto__
プロパティは同じものをA.prototype
指します。最も重要なのは、ステップ3:関数A()
が再度実行されることです。つまり、関数を含むプロパティをa2
取得しhey
ます。a1
およびa2
という名前の2つのSEPARATE特性を有するhey
2つの別々の機能を指しています!これで、同じことをする同じ2つの異なるオブジェクトに重複する関数があります。おっと... new A
すべての関数宣言が2のようなものよりも多くのメモリを消費した後、で作成された1000個のオブジェクトがある場合、これがメモリに与える影響を想像できます。これを防ぐにはどうすればよいですか?
__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
注:一部の人々は内部のプロトタイププロパティをとして呼び出さない傾向があります。__proto__
この名前を投稿で使用して、Functional.prototype
2つの異なるものとしてプロパティを明確に区別しています。
__proto__
、.prototype
まったく違うものです。
ほとんどの場合、それらは基本的に同じですが、2番目のバージョンでは、オブジェクトごとに個別の関数ではなく、関数のインスタンスが1つしかないため、メモリが節約されます。
最初のフォームを使用する理由は、「プライベートメンバー」にアクセスするためです。例えば:
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番目の例は、そのクラスのすべてのオブジェクトのインターフェースを変更します。
x
。そのプロトタイプAの新しいインスタンスを割り当てられているすべてのオブジェクトのために利用可能function B () {}; B.prototype = new A(); var b = new B(); b.x() // Will call A.x if A is defined by first example;
の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番目の例では、関数の単一のコピーがすべてのインスタンスで共有されます。
違いは何ですか?=>たくさん。
このthis
バージョンは、カプセル化、つまりデータの非表示を可能にするために使用されていると思います。プライベート変数の操作に役立ちます。
次の例を見てみましょう。
var AdultPerson = function() {
var age;
this.setAge = function(val) {
// some housekeeping
age = val >= 18 && val;
};
this.getAge = function() {
return age;
};
this.isValid = function() {
return !!age;
};
};
これで、prototype
構造を次のように適用できます。
大人によって年齢は異なりますが、すべての大人が同じ権利を取得します。
そのため、これではなくプロトタイプを使用して追加します。
AdultPerson.prototype.getRights = function() {
// Should be valid
return this.isValid() && ['Booze', 'Drive'];
};
ここで実装を見てみましょう。
var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )
var p2 = new AdultPerson;
p2.setAge(45);
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***
お役に立てれば。
私はこれが死の答えになっていることを知っていますが、速度の違いの実際の例を示したいと思います。
ここでは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
は、慣れているとおりに呼び出すことができる関数(オブジェクトとも考える)です。これには、プロパティ(関数を持つオブジェクト)があります。ときに呼び出されるいくつかの魔法を行い、かつ拡張呼び出される関数、関数内で定義されたメソッドを持つ(オブジェクトと思います)。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
。つまり、単にに委譲されます。
これは実際には、単純化された形式のプロトタイプパターンのもう1つの形式であり、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
例では変数)。
これにより、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でクラスを定義する方法を説明しようとしていました。これを反映して変数名が変更されました。
initialize
とx methods do not refer to the
同じですA
が、グローバルプロパティです。インスタンスのプロパティthis._instance_var
を使用する場合に使用します。_instance_var
A
他の回答で説明したように、プロトタイプ内の関数は、インスタンス化ごとに作成される関数ではなく、すべてのインスタンス化と共有されるため、これは実際にはパフォーマンスの考慮事項です。
これを示すためにjsperfをまとめました。クラスをインスタンス化するのにかかる時間には劇的な違いがありますが、実際に関連するのは、多くのインスタンスを作成している場合のみです。