オブジェクト
今まで扱ってきたJavaScriptの「値」は、文字列、数値、論理値の3つでした。オブジェクトは、複数の値をひとまとまりにして名前と値のペアで管理できる、新たな種類の値です。また、JavaScriptにおけるオブジェクトではない値を総称して、プリミティブな値といいます。
オブジェクトの生成
オブジェクトを生成するには、{
から}
までで表されるオブジェクトリテラルを用います。括弧内では、名前: 値
のペアをコンマで区切って記述します。
tip
リテラルとは、値を直接生成するための構文です。たとえば、3
は数値を生成するための数値リテラルですし、'Hello'
は文字列を生成するための文字列リテラルです。
オブジェクトの内部にアクセスするためには、ドット記法(.
)またはブラケット記法([]
)を用います。多くの場合、student1.name
とstudent1['name']
は等価です。可読性の観点からドット記法を用いる場合がほとんどですが、ブラケット記法では内部に式を記述できるため、アクセスするプロパティを動的に制御することができます。
ネストされたオブジェクト
student1.name
やstudent1.age
を、student1
のプロパティと呼びます。プロパティには任意の値を含むことができるため、当然のことながらオブジェクトのプロパティにオブジェクトを指定することもできます。
上記の例において、student2
のscores
プロパティには、オブジェクト{ math: 90, science: 80 }
が指定されています。このオブジェクトのmath
プロパティにアクセスするために、student2.scores.math
と記述しています。
オブジェクトを引数や戻り値に持つ関数
オブジェクトも値の一種ですので、当然のことながら関数の引数として渡したり、戻り値として返したりすることができます。
上の例では、introduce
関数にname
プロパティとage
プロパティを持つオブジェクトを渡しています。
オブジェクトと参照
次のコードの実行結果を予想してみてください。
驚くべきことに、このプログラムの実行結果は花子
になります。というよりそもそも、const
で宣言したはずの変数hanako
に再代入が行われているように見えますが、これは許されるのでしょうか。
この結果のカラクリは、JavaScriptの持つ参照という仕組みにあります。実は、
のようにオブジェクトリテラルを使用したとき、この式の値は、オブジェクトそのものではありません。オブジェクト自体はメモリ(コンピューターが一時的に値を保存しておく場所)に生成されるのですが、その式の値は生成されたオブジェクトへの参照、つまり場所を指し示す値でしかないのです。
などとしてもtaro
自体が書き換えられるわけではなく、参照が指し示す値を書き換えているだけに過ぎません。このため、const
による制約は満たされているのです。
上の例では、taro
の値をhanako
に代入することにより、taro
が持っていたオブジェクトへの参照と同じものをhanako
が持つことになります。参照先のオブジェクトは全く同じものですので、hanako.name
を変更した場合、taro.name
も書き変わってしまうことになるのです。
課題
以下のコードを実行したのち、変数sakura
はどのような値となるでしょうか。
なお、オブジェクトの中身を見るためには、開発者ツールを利用すると便利です。ネストされたオブジェクトも、ツリー形式で簡単に表示できます。console.log
をしたり、ブレークポイントで止めたりして変数の値を確認してみましょう。debugger
文を使用することもできます。