要するに:
new something2() instanceof something2 === false
関連して、プロトタイププロパティを使用するように例を拡張する場合
Something.prototype.method = function () { };
something2.prototype.method = function () { };
後者の場合、プロトタイプは継承されないことがわかります。
typeof (new Something()).method === "function"
type (new something2()).method === "undefined"
本当の答えは、まったく異なる基盤となる機械を利用しているということです。withをnew
呼び出すと、[[Construct]]メカニズムが呼び出されます。このメカニズムでは、コンストラクターのプロパティに従って[[Prototype]]プロパティを設定し.prototype
ます。
しかし、[[Construct]]アルゴリズムのステップ8〜10で面白いことが起こります。新しい空のオブジェクトを設定し、その[[Prototype]]をアタッチした後、実際のオブジェクトに[[Call]]を実行します。この新しいempty-plus-prototypeオブジェクトをとして使用するコンストラクターthis
。そして、ステップ9で、そのコンストラクターが何かを返したことが判明した場合---this
セットアップにすべての時間を費やした、プロトタイプにバインドされた、オブジェクトとして渡されたオブジェクトを破棄します。
注:オブジェクトの[[Prototype]](コンストラクターの]とは異なります.prototype
)には、次のコマンドでアクセスできますObject.getPrototypeOf
。
Object.getPrototypeOf(new Something()) === Something.prototype // steps 5 & 6
Object.getPrototypeOf(new something2()) === Object.prototype // default
いくつかのメタ質問に答えるには:
something2
いいえ、これはファクトリー関数でありコンストラクターではないため、大文字にしないでください。何かが大文字になっている場合、コンストラクターのセマンティクスを持つことが期待されますnew A() instanceof A
。
- グローバル名前空間を破壊する危険性が心配な場合は、ファイルの先頭に配置して、厳密モード
"use strict";
の使用を開始する必要があります。strictモードの多くの優れたクリーンアップの1つは、this
デフォルトundefined
でグローバルオブジェクトではなく、に設定されることです。たとえば、コンストラクターを指定せずにコンストラクターを呼び出すと、コンストラクターnew
がプロパティをにアタッチしようとしたときにエラーが発生しundefined
ます。
- ファクトリ関数(別名「クロージャパターン」)は、次の場合に限り、一般にコンストラクタとクラスの合理的な代替手段です。(b)そのオブジェクトのインスタンスをあまり多く構築しない。後者は、クロージャパターンで、すべてのメソッドの新しいインスタンスをすべての新しく作成されたオブジェクトにアタッチするためです。これは、メモリ使用量には適していません。クロージャパターンの最大の見返りであるIMOは、「プライベート」変数を使用できることです(これは良いことであり、他の人に言わせないでください:P)。