最初の違いは次のように要約できます:インスタンスをthis
指します。クラスのをます。Definitionをprototype
指します。
次のクラスがあるとしましょう:
var Flight = function ( number ) { this.number = number; };
そのため、ここthis.number
ではクラスのすべてのインスタンスにアタッチしています。Flight
独自のフライト番号が必要ます。
var flightOne = new Flight( "ABC" );
var flightTwo = new Flight( "XYZ" );
対照的に、prototype
すべてのインスタンスがアクセスできる単一のプロパティを定義します。
フライト番号を取得したい場合は、次のスニペットを書くだけで、すべてのインスタンスがこの新しくプロトタイプ化されたオブジェクトへの参照を取得します。
Flight.prototype.getNumber = function () { return this.number; };
2番目の違いは、JavaScriptがオブジェクトのプロパティを検索する方法に関するものです。あなたが探しているときObject.whatever
、JavaScriptはメインまでずっと行きます Objectオブジェクト(他のすべてのものが継承しているオブジェクト)に到達し、一致するものが見つかるとすぐにそれを返すか呼び出します。
しかし、それはプロトタイプ化されたプロパティでのみ起こります。だから、もしあなたがより高い層のどこかにいるならthis.whatever
、JavaScriptはそれを一致と見なさず、検索を続行します。
それが実際にどのように起こるか見てみましょう。
[ほとんど]すべてがJavaScriptのオブジェクトであることに注意してください。これを試して:
typeof null
次に、内部の内容を確認しましょうObject
(大文字O
と.
最後に注意してください)。Google Chromeのデベロッパーツールでを入力すると、.
その特定のオブジェクト内で使用可能なプロパティのリストが表示されます。
Object.
次に同じことを行いFunction
ます:
Function.
name
メソッドに気付くかもしれません。行って起動して、何が起こるか見てみましょう:
Object.name
Function.name
それでは、関数を作成しましょう。
var myFunc = function () {};
そして、name
メソッドもここにあるかどうかを見てみましょう:
myFunc.name
空の文字列を取得する必要がありますが、大丈夫です。エラーや例外は発生しません。
では、その神のようなものに何かを追加しObject
て、他の場所でも同様に入手できるかどうかを確認しましょう。
Object.prototype.test = "Okay!";
そしてそこに行きます:
Object.prototype.test
Function.prototype.test
myFunc.prototype.test
すべての場合であなたは見るべき"Okay!"
です。
各メソッドの長所と短所については、各オブジェクトのプロパティ全体をコピーするのではなく、すべてのインスタンスへの参照を保持するため、プロトタイピングを「より効率的な」方法として考えることができます。一方、それはあなたが本当に理由を正当化することができるまでの大きなノーノーである密結合の例です。this
コンテキストに関連しているため、かなり複雑です。インターネットで無料で多くの優れたリソースを見つけることができます。
つまり、どちらの方法も単なる言語ツールであり、それはあなたとあなたが解決しようとしている問題に本当に依存しており、より適切なものを選択します。
クラスのすべてのインスタンスに関連するプロパティが必要な場合は、を使用しますthis
。すべてのインスタンスで同じように機能するプロパティが必要な場合は、を使用しますprototype
。
更新
サンプルスニペットに関して、最初のサンプルはSingletonの例です。そのため、this
オブジェクト本体内で使用するのが理にかなっています。このようにモジュール化することで、サンプルを改善することもできます(常に使用する必要はありませんthis
)。
/* Assuming it will run in a web browser */
(function (window) {
window.myApp = {
...
}
})( window );
/* And in other pages ... */
(function (myApp) {
myApp.Module = {
...
}
})( myApp );
/* And if you prefer Encapsulation */
(function (myApp) {
myApp.Module = {
"foo": "Foo",
"bar": function ( string ) {
return string;
},
return {
"foor": foo,
"bar": bar
}
}
})( myApp );
最初に使用しているので、あなたの第二のスニペットは、そのあまり意味がないthis
と、後であなたがそれをハックしようとしているprototype
ので、仕事をしない、this
より優先されますprototype
。そのコードからどのような期待があり、どのように機能していたのかはわかりませんが、リファクタリングすることを強くお勧めします。
更新
this
優先順位について詳しく説明するためにprototype
、例を示して説明の方法を説明しますが、バックアップする外部リソースはありません。
例は非常に簡単です。
var myClass = function () { this.foo = "Foo"; };
myClass.prototype.foo = "nice try!";
myClass.prototype.bar = "Bar";
var obj = new myClass;
obj.foo; // Still contains "Foo" ...
obj.bar; // Contains "Bar" as expected
私たちが知っているように、説明はthis
文脈に関連しています。そのため、コンテキストの準備ができるまで存在しません。コンテキストの準備ができたら?新しいインスタンスが作成されているとき!あなたは今残りを推測する必要があります!prototype
定義はありthis
ますが、その時点で作成される新しいインスタンスがすべてであるため、優先する方が理にかなっています。