https://developer.mozilla.org/ja/docs/Web/JavaScript
まずはここを見る。
JavaScript のプロトタイプ継承について prototype
プロパティと constructor
プロパティおよびコンストラクタ関数[^1]を中心に理解します。
Function
コンストラクタ関数のインスタンスです。しかし new 演算子とともに使用されたときにインスタンスを生成するコンストラクタ関数にもなりますFunction
自身もコンストラクタ関数です)Function
コンストラクタ関数のインスタンス [^1] は prototype
プロパティを持ちます\_\_proto\_\_
を持ちます(現在は \_\_proto\_\_
を直接参照することは非推奨であり Object.getPrototypeOf()
を使います)constructor
プロパティを持ちます[^1]: 関数が単純な関数なのかコンストラクタ関数なのかは形式ではなく new での呼び出しを想定しているかで決まります。
function Foo(x, y) {
/*
* 返却するインスタン用オブジェクトを作成
*/
// this = new Object();
this.x = x;
this.y = y;
/*
* return がなくても this を返す
*/
// return this;
}
console.log(Array.prototype === Object.getPrototypeOf(['a', 'b'])); // true
console.log(Object.prototype === Object.getPrototypeOf(Array.prototype)); // true
console.log(Array.constructor === Function); // true
console.log(Object.constructor === Function); // true
console.log(typeof Function.prototype); // function
console.log(typeof Object.prototype); // object
console.log(((x:number) => x).constructor === Function);
console.log(Function.prototype === Object.getPrototypeOf((x:number) => x));
型 | コンストラクタ関数 | コンストラクタ関数ショートハンド |
---|---|---|
オブジェクト | Object |
{} |
配列 | Array |
[] |
関数 | Function |
なし |
// 例
const a = ['a', 'b']; // Array のショートハンド
class Foo {};
const f = new Foo();
コンストラクタ関数
?関数が単純な関数なのかコンストラクタ関数なのかは形式ではなく new での呼び出しを想定しているかで決まります。
// 単純な関数
function Sum(x, y) {
return x + y;
}
// 単純な関数として実行
Sum(1, 2);
// 3
// コンストラクタ関数
function Sum(x, y) {
this.x = x;
this.y = y;
}
Sum.prototype.add = function(x, y) {
return this.x + this.y
}
// new で生成
const instance = new Sum(1, 2);
instance.add();
すべてのオブジェクトインスタンスは、インスタンスを生成したコンストラクタ関数のprototypeにリンクする秘密のプロパティ(__proto__)を持っています。この秘密のリンクを使ってインスタンスのコンストラクタ関数のprototypeプロパティを取得できます。
開眼!JavaScript 042
※ 「すべてのオブジェクトインスタンス」はコンストラクタ関数も含みます。
後述するとおりコンストラクタ関数( Function
のインスタンスがコンストラクタ関数か単純な関数かは new を使った呼び出しを想定しているかによる)は __proto__ と prototpype の両方を持つ。
// []は配列のリテラルコンストラクタ関数
const a = ['a', 'b'];
// __proto__は非推奨なので、かわりにObject.getPrototypeOf()を使用
// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
Array.prototype == Object.getPrototypeOf(a); // true
// クラスもカスタムコンストラクタ関数の糖衣構文
class Foo {};
const foo = new Foo();
Foo.protyotype === Object.getPrototypeOf(foo); // true
8.3 prototypeプロパティはすべてのFunction()インスタンスに自動的に付与される
開眼!JavaScript p111
Array
や Number
)は、Function
コンストラクタ関数のインスタンスfunction Hoge() { /* コード */}
は、Function
コンストラクタ関数のインスタンスコンストラクタ関数
は prototype
プロパティを持つ// カスタムコンストラクタ関数
function Hoge() {};
Hoge.constructor === Function; // true
typeof Hoge.prototype; // object
// クラス
class Foo {};
Foo.constructor === Function; // true
typeof Foo.prototype; // Object
そしてFunction()のインスタンスで自動的に付与されたprototype
プロパティの__proto__
にはObject
が設定されている。
コンストラクタを使って作成されたインスタンスは自身を生成したコンストラクタ関数にポイントされたconstructorプロパティを持つ。
ref. 開眼!JavaScript 28
// 配列インスタンス
['a', 'b'].constructor == Array; // true
Array.constructor === Function; // true
// クラス
class Foo {};
const foo = new Foo();
foo.constructor === Foo;
Foo.constructor === Function;
型 | リテラル | コンストラクタ関数 |
---|---|---|
オブジェクト | {} |
Object |
数値 | 123 |
Number |
真偽値 | true or false | Boolean |
文字列 | 'foo' |
String |
配列 | [] |
Array |
関数 | なし | Function |