自分整理用、javascriptの関数オブジェクトと__proto__とprototype

http://d.hatena.ne.jp/m-hiyama/20050909/1126235062
http://www.google.co.jp/search?q=javascript+function+%E7%B6%99%E6%89%BF&btnG=%E6%A4%9C%E7%B4%A2&hl=ja&lr=lang_ja&inlang=ja&safe=off&sa=2** 関数はオブジェクトである


function f() {}
f.propA = 'test';
alert(f.propA); // → test
具体的には関数オブジェクトという、特別な種類のオブジェクトである。

関数オブジェクトは、通常のオブジェクトとは別の型のオブジェクトである通常のオブジェクトはコンストラクタとして使うことが出来ない。


var obj = new Object();
var obj2 = new obj(); // error関数オブジェクトはコンストラクタとして使って、新しいオブジェクトを生成することが出来る。

function f() {}
var obj = new f(); // 成功コンストラクタによって生成されたオブジェクトは、通常のオブジェクトである。

function f() {}
var obj = new f(); // 成功
var obj2 = new obj(); // error
//(ただし、「Function」をコンストラクタとして生成したオブジェクトは例外。
// var func = new Function();とやった場合、はfuncは関数オブジェクトになる)

全オブジェクトは__proto__というメンバを持っている

関数オブジェクトも通常のオブジェクトも、__proto__という特殊なメンバを持っている。
これはprototypeメンバ別のメンバである。
javascriptでは、オブジェクトに持っていないメンバを参照しようとしてメンバが存在しなければ、__proto__にそのメンバが存在しないかを調べに行く。__proto__にもそのメンバが存在しなければ、__proto__の__proto__にそのメンバが存在しないかを調べに行く。そうして、__proto__がnullになるまで上位の__proto__にメンバが存在しないか探しに行く。** 生成されたオブジェクトは、コンストラクタとして使われた関数オブジェクトのprototypeを__proto__として持っている


      __proto__←━┓        __proto__
        |    ┗━━prototype   |
        |         |     |
[newされたオブジェクト] ← [newに使われた関数オブジェクト]
newによって生成されたオブジェクトは、コンストラクタとして使われた関数オブジェクトのprototypeを__proto__として持っている。だから以下のようなコードが成立する。

String.prototype.outputEx = function () { alert('【' + this + '】');
var str = new String("test");
str.outputEx();

考え方イメージ

各オブジェクトを人としてイメージした場合、関数オブジェクトは、学校経営者。
関数オブジェクトの持っているprototypeは教師。
生成されたオブジェクトはその学校を卒業した生徒。
……というイメージで考えて理解した。