「開眼!JavaScript」という本をオススメしてもらって、読んだら本当に面白かった(普段使っているけど改めて勉強になった)です。
タイトルにもある通り、この本を読んで今まで特に気にしていなかったが、ハッとさせられたJavaScriptの本質みたいな部分です。
プリミティブ型とオブジェクト型
プリミティブ型を生成して複製すると格納している値をコピーします。
そのため、複製した値を変更しても、元の変数の値は変更されません。
hoge = 'hoge'
//'hoge'
hogeCopy = hoge
//'hoge'
hogeCopy = 'hogehoge'
//'hogehoge'
hoge
//'hoge'
typeof hoge
//'string' でプリミティブ型
それに対して、
オプジェクト型は、複製するとオブジェクトのアドレスをコピーするため、
複製先のオブジェクトを変更すると、元のオブジェクトも変更されてしまう。
obj = new Object()
//{}
obj.hoge = 'hoge'
//'hoge'
obj
//{hoge: 'hoge'}
objCopy = obj
//{hoge: 'hoge'}
objCopy.hoge = 'hogehoge'
//'hogehoge'
objCopy
//{hoge: 'hogehoge'}
obj
//{hoge: 'hogehoge'} で、objCopy.hogeを変更すると、objも変更される
typeof obj
//'object' でオブジェクト型
typeof objCopy
//'object' でオブジェクト型
ここまでは、JavaScriptを実装している上で、なんとなくイメージができる。
プリミティブ型なのにラッパーオブジェクトのメソッドが使える
typeof
で、プリミティブ型であることを確認したはずなのに、無意識的にhoge.length
のようなメソッドを使っていました。
hoge
//'hoge'
hoge.length
// 4
typeof hoge
//'string'
Javaでは、プリミティブ型には振る舞い(メソッド)を持たないので、参照型にする必要があります。
https://morizyun.github.io/java/type-primitive-reference.html
JavaScriptでは、この一連の処理をすべてバックグラウンドで自動で行います。
プリミティブ型ですが、目的のメソッドが呼び出されたタイミングでラッパーオブジェクトを生成して
実行後は破棄してプリミティブ型に戻ります。
これが、「JavaScriptではすべてがオブジェクトである」ではなく、
「JavaScriptではすべてがオブジェクトのようなふるまいをする」という意味でした。
開眼したような気がしました。