【JavaScript】オブジェクト（+配列）について復習する



# 目次

[1. 背景](#1背景)
[2. 環境](#2環境)
[3. オブジェクトって何？](#3オブジェクトって何)
[3-1. （補足）シンボルについて](#3-1補足シンボルについて)
[4. オブジェクトの使い方](#4オブジェクトの使い方)
[4-1. 追加する](#4-1追加する)
[4-2. 取り出す](#4-2取り出す)
[4-2-1. 値（バリュー）のみ](#4-2-1値バリューのみ)
[4-2-2. 名前（キー）のみ](#4-2-2名前キーのみ)
[4-2-3. 全体](#4-2-3全体)
[4-3. あるかどうか確認する](#4-3あるかどうか確認する)
[4-4. 削除する](#4-4削除する)
[5. 配列とオブジェクトの違い](#5配列とオブジェクトの違い)
[6. まとめ](#6まとめ)
[7. 参考](#7参考)
[8. 最後に](#8最後に)

# 1.背景

実務でJavaScriptを使っているのですが、
:man:「オブジェクトについて復習しといてね」
と教育係の先輩に言われました。

そこで今回はオブジェクト（+配列）についてまとめていきたいと思います。


# 2.環境

- windows10 バージョン21H2


# 3.オブジェクトって何？

[JSPrimer](https://jsprimer.net/basic/object/)ではで以下のように説明されています。

> オブジェクトはプロパティの集合です。プロパティとは名前（キー）と値（バリュー）が対になったものです。 プロパティのキーには文字列または`Symbol`が利用でき、値には任意のデータを指定できます。 また、1つのオブジェクトは複数のプロパティを持てるため、1つのオブジェクトで多種多様な値を表現できます。
> 

空のオブジェクトを作成して宣言します。

```javascript
const humanObj = {};
```

また、初期値を設定して作成・宣言したり、中括弧`({})`でリスト化して宣言することも可能です。

```javascript
//　初期値を設定
const humanObj = new Object();
humanObj.name = "Taro";
humanObj.from = "Tokyo";
humanObj.year = 1989;

//　中括弧({})でリスト化
const humanObj = {
	// 名前（キー）: 値（バリュー）。キーのクォーテーションは省略可能。
	"name": "Taro",
    "from": "Tokyo",
    "year" : 1989
};
```

:::note
オブジェクト：キーとバリューが対になっている、プロパティの集まり
:::

## 3-1.（補足）シンボルについて

プロパティのキーには文字列または`Symbol`が利用できる、とありました。

シンボルの特徴は以下です。

- ユニークである（＝重複しない）ことが保証されている
- 値そのものをデータとして使用できず、`toString()`を呼び出す必要がある

```javascript
const gender = Symbol();
const age = Symbol();
const humanObj = {
    "name": "Taro",
    "from": "Tokyo",
    "year" : 1989,
    [gender] : "man", // シンボル
    [age] : 35 // シンボル
};
console.log(gender); //Symbol()
console.log(age); //Symbol()
console.log(humanObj[gender]); //man
console.log(humanObj[age]); //35
```

少し前のコードで定義した`humanObj`に`gender`と`age`を追加して宣言しました。

`humanObj[gender]`（`オブジェクト[シンボル値]`）とするとアクセスできます。

`console.log();`で`gender`と`age`を確認すると`Symbol()`が返ってきますが、`toString()`で文字列が`Symbol()`と生成されて出力されている状態です。

なので、見た目は同じ、中身は別物です。

他にも

- 列挙できない（forEach文で除外される）
- JSONに変換できない

といった側面もあります。逆に他のコードからアクセスしたり上書きされることがないため、状況に応じて使い分けられると良いのかなと思います。

※`forEachメソッド`：繰り返し処理を実行したいときに使用します。どこでも使用できる`for`文と異なり、配列のデータに対してのみ実行可能な処理です。


# 4.オブジェクトの使い方

## 4-1.追加する

ドット記法またはブラケット記法で追加することができます。

先ほどの`humanObj`に`gender`と`age`をそれぞれの記法で追加してみます。

```javascript
const humanObj = {
	"name": "Taro",
    "from": "Tokyo",
    "year" : 1989
};
humanObj.gender = "man"; //ドット記法
humanObj["age"] = 35; //ブラケット記法
console.log(humanObj); //=> {name: 'Taro', from: 'Tokyo', year: 1989, gender: 'man', age: 35};
```
`オブジェクト.プロパティ`もしくは、`オブジェクト["プロパティ"]`とすることで追加できます。

オブジェクトそのものを出力すると、追加されていることが確認できます。

## 4-2.取り出す

以下のコードをベースに取り出します。

```javascript
const humanObj = {
	// 名前（キー）: 値（バリュー）。
	"name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};
```

### 4-2-1.値（バリュー）のみ

```javascript
const humanObj = {
	"name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

//取り出してみる
console.log(humanObj.gender); //=> man
console.log(humanObj["age"]); //=> 35
```

`オブジェクト.プロパティ`もしくは、`オブジェクト["プロパティ"]`とすることで取り出すことができます。

配列で取得する場合は`Object.values()`で取得します。

```javascript
const humanObj = {
	"name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

console.log(Object.values(humanObj));
//(5) ['Taro', 'Tokyo', 1989, 'man', 35]
```

### 4-2-2.名前（キー）のみ

配列で取得する場合は`Object.keys()`で取得します。

```javascript
const humanObj = {
	"name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

console.log(Object.keys(humanObj));
//(5) ['name', 'from', 'year', 'gender', 'age']
```

また`forEachメソッド`と組み合わせて出力することもできます。

```javascript
const humanObj = {
	"name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

const keys = Object.keys(humanObj); //一度配列にする
keys.forEach(key => {
    console.log(key);
});
//name
//from
//year
//gender
//age
```

### 4-2-3.全体

配列で取得する場合は`Object.entries()`で取得します。文字列をキーとした列挙可能なプロパティの組 `[key, value]`を返します。

```javascript
const humanObj = {
    "name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

for (const [key, value] of Object.entries(humanObj)) {
    console.log(`${key}: ${value}`);
}
//name: Taro
//from: Tokyo
//year: 1989
//gender: man
//age: 35
```

## 4-3.あるかどうか確認する

ここでは「あるかどうか確認して、なければ追加する」ということをやっていきたいと思います。

一例として`in演算子`を紹介させて頂きます。
`in演算子`は、オブジェクトの中に指定されたプロパティが存在する場合に `true` を返します。

```javascript
const humanObj = {
    "name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

if ( "age" in humanObj === false ) {
    humanObj["age"] = 35;
} else {
    console.log("既に登録済みです"); //こちらが表示される
}
```

## 4-4.削除する

削除したいときには`delete演算子`を使用します。

取り出すときと同様で、頭にdeleteをつけて`オブジェクト.プロパティ`もしくは、`オブジェクト["プロパティ"]`とすることで削除することができます。

```javascript
const humanObj = {
    "name": "Taro",
    "from": "Tokyo",
    "year": 1989,
    "gender": "man",
    "age": 35
};

delete humanObj.gender; //=> man を削除
delete humanObj["age"]; //=> 35 を削除
console.log(humanObj); //=> {name: 'Taro', from: 'Tokyo', year: 1989}
```


# 5.配列とオブジェクトの違い

配列：添字（インデックス）を使って格納されたデータを参照します。
インデックスは0から始まります。

```javascript
const humanArr = ["Taro", "Tokyo", 35];
console.log(humanArr[0]); //=> Taro
```

オブジェクト：プロパティを使って格納されたデータを参照します。

数値だけが順番に並んでいて「●番目のデータを取得したい」ときは配列、「複数のデータをまとめて扱ったり、より具体的なデータを取得したい」ときはオブジェクトが適切です。

また、JavaScriptの場合、配列はオブジェクトに含まれます。


# 6.まとめ

オブジェクトについて復習することで、理解が深まりました。
また、配列との違いが明確になったので適切に使用していきたいと思います。


# 7.参考

https://jsprimer.net/basic/object/

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Working_with_Objects

https://note.affi-sapo-sv.com/js-symbol.php

https://ja.javascript.info/symbol

https://techacademy.jp/magazine/45055

https://qiita.com/chihiro/items/eb8c7b2ceee5274a4a8f

https://javascript.keicode.com/lang/object-object-property-add.php

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/values

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

https://webukatu.com/wordpress/blog/20811/

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/delete

https://atmarkit.itmedia.co.jp/ait/articles/1011/29/news109.html

https://step-learn.com/article/javascript/052-array-object.html


# 8.最後に

間違いやおすすめのコードの書き方など、何かありましたらどんどん言っていただけると幸いです。

読んでいただきありがとうございました！