__proto__・prototype (2) : JavaScript

Pocket

__proto__・prototype (1) : JavaScriptで__proto__プロパティとprototypeプロパティについて書いた。そのつづきを書く。

プロトタイプチェーンの分かり易い図と解説。
» Javascript Object Hierarchy
» prototypeと__proto__ – mfumiの日記

  • インスタンスは自身の生成に使われたコンストラクタ[1]]のprototypeへの参照を持つ。この参照を暗黙リンク(implicit prototype link)と呼ぶ[2]
    • 関数オブジェクト(Function Object)はFucntion.prototypeへの暗黙リンクを持つ
      (function Foo() {}; Foo.__proto__ = Function.prototype; // true)。
    • 関数オブジェクトのインスタンスは関数オブジェクトのprototypeへの暗黙リンクを持つ
      (funcion Foo() {}; var f = new Foo(); f.__proto__ = Foo.prototype; // true)。
    • prototypeはオブジェクトでありObjectから生成されるのでObject.prototypeを継承する
      (function Foo() {}; Foo.prototype.__proto__ = Object.prototype; // true)。
    • オブジェクトリテラル{}はnew Object()のショートカット。

[1] インスタンスの生成に使うオブジェクトをコンストラクタと呼ぶ。
[2] 暗黙リンクを__proto__プロパティとして公開している実装(Mozillaなど)がある。

// ■ 基本
// __proto__はプロトタイプチェーンをたどる為のプロパティ。
// prototypeは関数オブジェクトを拡張するためのプロパティ。



// ■ 関数として利用する
// プロトタイプチェーン
// personal.__proto__(=Function.prototype) ⇒
// Function.prototype.__proto__ = Object.prototype
// 独自関数オブジェクト
var personal = function () {
    return 'this is personal function';
};
// Functionオブジェクトを拡張
Function.prototype.hello = function () {
    return 'this is Function';
};
// 独自関数の実行
document.write(personal());
// 独自関数のプロトタイプチェーンをたどり、
// Functionオブジェクトのメソッド実行
// personal.__proto__ = Function.prototype
document.write(personal.hello());



// ■ コンストラクタとして利用
// protoypeで独自関数オブジェクトを拡張
personal.prototype.name = 'Personal Object';
personal.prototype.hello = function () {
    return 'this is ' + this.name;
};
// インスタンスを作成
var ins = new personal();
// インスタンスのプロトタイプチェーン
// 独自関数のメソッドを実行
// ins.__proto__=personal.prototype
document.write(ins.hello());
// Object.prototypeのメソッドを実行
// ins.__proto__(=personal.prototype) ⇒
// personal.prototype.__proto__(=Object.prototype)
document.write(ins.toString());

constructor

function Foo (name) {
    this.name = name;
}
Foo.prototype.getName = function () {
    return this.name;
}
console.log(Foo.constructor); // --- (1) Function
console.log(Foo.prototype.constructor); // --- (2) Foo

(1)のconstructorプロパティは生成に使われたコンストラクタが入る。(2)のprototypeのconstructorプロパティには自身が設定する。関数オブジェクトはコンストラクタをしたものであってもnewされるまでは自分がコンストラクタとして利用されるのかはわからないのでprototypeオブジェクトのconstructorプロパティに自身を設定する。

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。