オブジェクト [JavaScript]

オブジェクトとは？

配列同様、データ構造の一つ。
配列と同じように複数のデータを持っておくことができます。

オブジェクトは**プロパティ**の集合です。
プロパティとは名前（キー）と値（バリュー）が対になったものです。 

配列のようにインデックスで要素にアクセスするのではなく、
キーを使ってデータにアクセスします。


例：

・変数は１つのデータしか格納できません。
・配列はさまざまな型のデータを複数格納できるのが特徴です。

ではオブジェクトの特徴は？

そこで、例としてユーザー登録のデータを配列で格納したコードを見てみます。
```js
const array = ["山田太郎",30,"yamada@example.com","090-xxxx-xxxx"];
```

上記コードを見ると、「山田太郎」が名前を意味しているのはなんとなく分かりますが、「30」は何を指しているのか分かりづらいし全体としても見づらい印象を受けます・・・

まったく同じ内容を、今度はオブジェクトで記述すると以下のようになります。
```js
const obj = {
  name: '田中太郎',
  age: 30,
  email: "yamada@example.com",
  phonenumber: "090-xxxx-xxxx"
};
```

上記コードを見ると、田中太郎や 090-xxxx-xxxxがなどが、それぞれ対応しているものを一目で確認することができ、「30」は年齢であることがプログラムを見ただけで理解できますね。

このようにオブジェクトは **「キー：値」** というペアでさまざまなデータを格納できるため、複雑な構造をしたデータをJavaScriptで扱う時に最適なわけです。


簡単にオブジェクトの概要について理解できたところで、
具体的な作り方や使い方についてみていきたいと思います。

## 目次：

- [オブジェクトの作り方](#オブジェクトの作り方)
    - [オブジェクトの中には色々なデータ型を入れてOK
](#オブジェクトの中には色々なデータ型を入れてok
)
- [オブジェクトの中のデータにアクセスする](#オブジェクトの中のデータにアクセスする)
    - [ドット（.）を用いる方法](#ドットを用いる方法)
    - [ブラケット（[]角カッコ）記法を用いる方法](#ブラケット角カッコ記法を用いる方法)
- [オブジェクトの中のデータの更新、追加](#オブジェクトの中のデータの更新追加) 


## オブジェクトの作り方

一般的なオブジェクトの作り方としては{ }波括弧を利用して以下のように記述します。

```js
const person = { firstName: "Taro", lastName: "Yamada"}
```

この1行で新しいオブジェクトを作成することができます。

１、対応しているキーと値のペアをそれぞれ作成します。
```js
firstName: "Taro"
lastName: "Yamada"
```
２、対応しているキーと値のペアの間は,(カンマ)で区切ります。

```js
person
```

```text:出力結果：
{
    firstName: "Taro",
    lastName: "Yamada"
}
```

personを参照すると、firstName、lastNameがそれぞれ存在し、
それぞれのキーに対応した値があることを確認できる。

### オブジェクトの中には色々なデータ型を入れてOK

例：

とあるサービスXについて。

投稿者のコメントを保持するオブジェクトがあったとします。
そのオブジェクトの中を少し覗いてみることにしましょう。
```js
const comment = {
    usename : "shisshiengineer",
    downVotes : 1,
    upVotes: 12,
    commentText: "とても参考になった！",
    tags: ["#駆け出しエンジニアと繋がりたい","#プログラミング"],
    isAuthor: true
};
```

上の例を見ていて分かる通り、オブジェクトには様々なデータ型を入れることができます。

低評価(downVotes)や高評価(upVotes)を表すところにはnumberの数値が入力され、
tagsには配列が入っています。
また、(ログイン者)isAuthorのところにはBooleanのtrueが入っています。
```js
comment
```

```text: 出力結果：
const comment = {
    usename : "yamada",
    downVotes : 11,
    upVotes: 249,
    commentText: "とても参考になった！",
    tags: ["#駆け出しエンジニア","#プログラミング"],
    isAuthor: true
}
```

##  オブジェクトの中のデータにアクセスする

配列の場合は、データにアクセスする際には、インデックスを使用していました。

例：

配列にアクセスする際には、角カッコ[]のなかにインデックスの取得したい値を入力してアクセスすることができた。
```js
let days = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];

days[0]
days[6]
```
```text:出力結果：
"Monday"
"Sunday"
```

### オブジェクトの場合は？？？

オブジェクトの場合はデータにアクセスする方法は**二種類**存在します。

・ドット（.）を用いる方法
・ブラケット（[]角カッコ）記法を用いる方法

順番に説明していきます。

### ドット（.）を用いる方法


オブジェクトにアクセスする方法の１つです。
定義したオブジェクトの後ろに.(ドット)をつけて、キーの値をその後ろに書くことで、キーに対応した値を取得することができます。

メリット：

・ .(ドット)を用いる方が簡単で直感的に値を取得することができます。

デメリット：

・キーが変数名と同じく識別子の命名規則を満たす必要があります。

// プロパティ名が数字から始まる識別子は利用できない
```obj.123; // NG```
// プロパティ名にハイフンを含む識別子は利用できない
```obj.my-prop; // NG```

など

```js
const obj = {
    key: "value"
};

const birthYear = {1999: 
```
```text:ドット記法で参照
console.log(obj.key);
```
```text:出力結果：
"value"
```

### ブラケット（[]角カッコ）記法を用いる方法

オブジェクトにアクセスする方法の１つです。
定義したオブジェクトの後ろに[](角カッコ)をつけて、キーの値をその後ろに書くことで、キーに対応した値を取得することができます。

メリット：
.(ドット)記法のように識別子の命名規則などを守る必要がない。
それにより、変数などの式も入れて値を取得することが可能。

デメリット：
.(ドット)記法よりも直感的でなく、記載が少し多い。


注意：
オブジェクトは、数値を入力することも可能だが、
・作るとき、及び、・使用するときには、
**キー**は、全てstringに変換されてしまう。（Symbolは例外）
```js
const obj = {
    key: "value"
};
```
```text:ブラケット記法で参照
console.log(obj["key"]); 
```


```text:出力結果：
"value"
```

##  オブジェクトの中のデータの更新、追加

オブジェクトの作り方、データへのアクセスを学んだところで、データの更新、追加の方法を見ていきたいと思います。

例：

定期テストの点数が入ったオブジェクトがあります。
このオブジェクトの中には、taroくんとjiroくんのテストの点数が入っています。

しかし、入力するときに間違えてjiroくんのテストの点数を78ではなく、75と入力してしまいました・・・
これを修正するには？

```js
const regularTest = {taro: 95, jiro: 75};

regularTest.jiro = 78

regularTest
```

.(ドット)を使ったアクセス記法を使い、
regularTest.jiroにアクセス。

そして、そのまま = で繋ぎ点数を書き換えれば完了です。

直感的でとてもわかりやすいですね。

```text:出力結果
{taro: 95, jiro: 78}
```

例２：

テスト結果の中にsaburoくんを追加するのを忘れていました・・・

このオブジェクトの中にsaburoくんを追加するには？

```js
regularTest.saburo = 85;
```
こちらもregularTestに.saburo
と.表記で新しく入れたいキーとそれに対応する値を入力すればOK

regularTestの中を確認するとsaburoくんも入ったオブジェクトが返ってくることを確認できます。

```text:出力結果：
{taro: 95, jiro: 78, saburo: 85 }
```

もちろん、[] (角カッコ)の場合でも同様に新しいキーと値をペアをオブジェクトに挿入することも可能です。

```js
const regularTest = {taro: 95, jiro: 75};

regularTest["saburo"] = 85 
```
```text:出力結果：
{taro: 95, jiro: 78, saburo: 85 }
```
:::note info
疑問：const 宣言なのにオブジェクトの中身を変更できるのはなぜ？

>JavaScript では、var、let、constの 3 種類の変数宣言がありますが、
constは一般的に定数を宣言する際に使用されます。
ですが、const で定義された変数が必ずしも完全に不変であるわけではありません。
特に、const で宣言されたオブジェクトや配列の場合、その変数自体の再代入はできませんが、オブジェクトのプロパティや配列の要素は変更することが可能です。
>
>この挙動は、const が変数への参照自体の不変性を保証する一方で、参照先のデータ（オブジェクトや配列の中身）の不変性までは保証しないために起こります。つまり、const で宣言されたオブジェクトや配列の参照を変更することはできませんが、その中身（プロパティや要素）の変更は可能ということです。この理解は、JavaScript を使用する際に変数の不変性を正しく扱うために重要になります。
:::

## 　まとめ

データ構造のデータの持ち方一つとっても色々な方法があり、それぞれにそれぞれのルールがちゃんと存在する。

そして、それを組み合わせて使用していくことも多いので、ごちゃごちゃにならないように一つ一つのルールを明確にしてちゃんと覚えておき、それを適切なところで使用できるように頭の片隅に置いておきたいと思います。