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)にしても、まずはオブジェクト自身のプロパティを参照しようとし、そこが未定義ならば継承元のプロパティを参照しようとする(プロトタイプチェーン)。
言い換えれば、常にプロトタイプ(継承元)を暗黙参照にしつつ、自身のプロパティが"真"なら継承元をレイヤーで覆い隠すという感じ。