CSSのようなprototype
CSS(Cascading Style Sheet)の継承
(IEでのバグは考慮しない)
まず前提として親→子へ継承するものとしないもの。
継承されるのはインラインなプロパティ。もっぱらfont関係。
- color,text-align,font-size,font-family,line-height...
ボックスのプロパティは継承しない(明示的にしない限り)。
- display,position,float,margin,padding,border...
例えば以下の指定がある
/*css*/ body{color:#000;} p{} span{color:#f00;}
<!--html--> <body> <p>おもろい<span>芸人</span>は?</p> </body>
おもろい芸人は?
まずbodyという親要素は「color:#000;」。
次の子要素pは何も指定しないので暗黙的に「color:#000;」を継承している。
そしてpの子要素spanには「color:#f00;」をセットする。
これにより、継承するはずの「color:#000;」を「color:#f00;」で上書きしている。
つまり、HTMLツリーでの下層要素は上書きしない限り、継承・Cascadeingし続ける。
CSSではこのように、抽象要素に書かれたものを、詳細要素(セレクタ)で上書きしていく。というのが基本概念。
(Firebugのおかげでこの継承の様子がよくわかる)
ということを踏まえると、
(部分的には)JavaScriptのprototypeが理解しやすくなる
prototypeオブジェクトの基本的なこと。
全ての関数オブジェクトにはprototypeというプロパティを持っている。
これは中身が空っぽの単純なオブジェクトであるが、その関数オブジェクトをコンストラクタとして生成(new)されたインスタンスは、そのコンストラクタのprototypeプロパティに代入されているオブジェクトに対し、暗黙の参照を持つということ。
function Parent(){} // コンストラクタ定義 Parent.prototype.name="red"; //prototypeオブジェクトに代入 var child=new Parent(); child.name; //prototypeの値を参照している >>> "red" child.name="blue"; //childオブジェクトのnameプロパティに"blue"を代入 child.name; //nameはchild自身が所持しているため、prototypeを参照しない >>> "blue" delete child.name; //childオブジェクトのnameを消してみる child.name; //自身のプロパティは消えるが、prototypeオブジェクトを探し参照する >>> "red"
CSSの継承と照らし合わせると、これに共通性を感じる。
オブジェクト(js)やセレクタ(css)にしても、まずはオブジェクト自身のプロパティを参照しようとし、そこが未定義ならば継承元のプロパティを参照しようとする(プロトタイプチェーン)。
言い換えれば、常にプロトタイプ(継承元)を暗黙参照にしつつ、自身のプロパティが"真"なら継承元をレイヤーで覆い隠すという感じ。