var block = { item: "coin" };
というオブジェクトをつくります。
console.log(block.item); // => "coin" console.log(block["item"]); // => "coin"
block の itemプロパティにアクセスすると "coin" という文字列が返ってきます。
console.log(block.color); // => undefined
設定していないプロパティ(例えば color とか)にアクセスしようとすると、基本的には undefined が返ってきます。
console.log(block.toString); // => function toString() { [native code] }
しかし、例えば toString プロパティにアクセスしてみると、関数が返ってきます。
自分ではメソッドを定義していないにもかかわらず、toStringメソッドがあるかのように振る舞うのです。
console.log(block.toString()); // => "[object Object]"
己のメソッドのように振る舞うので、当然実行することもできます。
では、この toStringメソッド はどこからやってきたものなのでしょうか。
正解を先に書いてしまうと、Object.prototype.toString です。
自分に所属していないプロパティ・メソッドにアクセスが有った際に、指定された関数のプロトタイプ(今回の場合はコンストラクタのプロトタイプ)を探しに行く姿勢。これがプロトタイプチェーンなのです。
プロトタイプチェーンの例
block.toString にアクセスしようとした際、
1.自分のメンバを探す
block.toString // => undefined
※ ここで見つからなくても諦めません
2.探しに行くべき場所を問い合わせる
block.__proto__ // => Object.prototype
※ __proto__は仕様で決まっているプロパティではありません。
3.教えられた場所を探しに行く
Object.prototype.toString // => function toString() { [native code] }
※ __proto__が空だったら諦めます。
4.見つかった値があれば返すのであたかも己のプロパティのように見える
block.toString // => function toString() { [native code] }
こんな流れとなります。
次回、__proto__とprototypeの関係でもう少し詳しいことを書きたいと思います。