JavaScript の型
前後しますが JavaScript には6個の型があります (処理系内部的/説明的には9個)。
- Undefined / undefined
- Null / null
- Boolean / true, false
- Number / 10, 0xff
- String / "foo", "fumino san love"
- Object / {foo: 123, bar: 456}
Object 型以外は Primitive であり、そう考えると Primitive vs Object の構造が想像できると思います。(リテラル undefined や null, 1, 2, "foo" とかは全部この型に対応しています) JavaScript における「オブジェクト」は Object 型の値のことで、Object 型以外は「プロパティ」や「メソッド」を持ったりはしていません。
プロパティアクセス演算子は Object 型へ必ず変換しますが、そのとき使われる ToObject は、undefined と null のときに TypeError をなげます。(この変換のおかげで Primitive 値の多くはオブジェクトのように扱うことができます)
割とよくみるであろう
TypeError: null has no properties TypeError: undefined has no properties
は、この ToObject への変換時におきているものです (殆どないし全部)。もし JavaScript でも Ruby と同じように「全てがオブジェクト」であるならば、上のようなエラーは絶対に起きないはず (オブジェクトであれば no properties はありえない) ですし、Object に定義されているメソッドが null や undefined に対しても使えるはずです。
null.toString();
undefined.valueOf();実行しなくてもわかるようにこのコードは TypeError がでます。JavaScript では「全てがオブジェクトというわけではない」ことは、この TypeError の背中が物語っています。