すべての関数にはprototype
プロパティがあり、関数オブジェクトの作成時に割り当てられ、から継承する新しく作成されたオブジェクトを指し、関数自体を指すプロパティObject.prototype
があります。constructor
prototype
プロパティの目的は、コンストラクター関数を使用して継承を実装する方法を提供することです。演算子を使用して関数を呼び出すと、new
そのコンストラクターのを継承する新しいオブジェクトが作成されますprototype
。
ここで、constructor
プロパティの目的は、オブジェクトを作成したコンストラクターを参照する方法を用意することです。次に例を示します。
function Foo () {}
// default value of the property:
Foo.prototype.constructor == Foo; // true
このプロパティはの「インスタンス」によって継承さFoo
れるため、オブジェクトの作成に使用されたコンストラクターを知ることができます。
var foo = new Foo();
foo.constructor == Foo;
関数のプロトタイプに新しいオブジェクトを割り当てると、この関係は失われます。
function Bar () {}
Bar.prototype = { inherited: 1 };
Bar.prototype.constructor == Bar; // false
Bar.prototype.constructor == Object; // true
また、関数のインスタンスにも影響します。
var bar = new Bar();
bar.constructor == Bar; // false
bar.constructor == Object; // true
もう1つの同様のケースは、コンストラクターを使用して2つ以上のレベルの継承がある場合です。最も一般的な方法は、関数間の継承関係を示すために使用されprototype
、2番目のレベルのプロパティを割り当てることです。
function Parent() {}
function Child () {}
Child.prototype = new Parent();
上記のコードにはいくつかの問題があります。まず、親コンストラクターのロジックを実行して継承関係を作成しますが、これは別の話です。上記の例では、オブジェクトconstructor
を完全に置き換えるため、プロパティも影響を受けます。Child.prototype
var child = new Child();
child.constructor == Parent; // true
constructor
割り当てた後にのプロパティの値をChild.prototype
replacereplaceすると、期待される動作が表示されます。
function Child() {}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child = new Child();
child.constructor == Child; // true