[Day8] データ型 part2

本記事は一人アドベントカレンダー企画の一つです。
[30代未経験エンジニアが25日後にJavaScriptをマスターするカレンダー](https://qiita.com/advent-calendar/2022)

[JAVASCRIPT.INFO](https://ja.javascript.info/)を元にJavaScriptを勉強していき、そこで学んだ知識をアウトプットしていきます。
２５日でJAVASCRIPT.INFOをやりきり、未経験エンジニアがJavaScriptをマスターする過程を投稿していきます。



## 5.7 Map と Set
### 知らない単語
- iterableとは
    - 反復可能プロトコル

### 学んだこと
- Map
Mapはキー付されたデータの集まりで、任意の型のキーを許可する
主なメソッド
new Map()は新しいmapを作る
map.set(key, value)はキーで、値を格納する
map.get(key)は指定されたキーの値を返却する
map.has(key)はキーが存在する場合に true を返し、そうでなければ false になる
map.delete(key)はキーで値を削除する
map.clear()はmapをクリアする
map.sizeは現在の要素の数である

mapはオブジェクトと違い、キーは文字列には変換されない
任意の型のキーが利用可能で、キーとしてオブジェクトを使うこともできる
例えば
```javascript
let bill = { name: "Bill" };

// 各ユーザに対し、訪問回数を保持する
let visitsCountMap = new Map();

// bill は map のキー
visitsCountMap.set(bill, 123);

alert( visitsCountMap.get(bill) ); // 123
```
このようにオブジェクトをキーとして使用することは、重要なMapの機能である

- Map での繰り返し/ループ

mapでループするためのメソッド
map.keys()はキーに対する iterable を返す
map.values()は値に対する iterable を返す
map.entries()はエントリ [key, value]　の iterable を返す
これは for..of でデフォルトで使われている

- Set
setは特別で、値の集合（キーなし）で、それぞれの値は一度しか現れない

setの主なメソッド
new Set(iterable)はsetを作る、オプションで値の配列からも可能
set.add(value)は値を追加し、set自身を返す
set.delete(value)は値を削除し、value が呼び出し時に存在すれば true, そうでなければ false を返す
set.has(value)はset の中に値が存在すれば true を返し、それ以外は falseである
set.clear()はset から全てを削除する
set.size()はset の要素数を返す
Setでは値は一度しか現れないので、同じ値での set.add(value) の繰り返しの呼び出しでは何もしない

### 感想
MapもSetもメソッドが多いので、正しく覚えておく。


## 5.8 WeakMap と WeakSet

### 知らない単語
- ユースケースとは
    - 利用者があるシステムを用いて特定の目的を達するまでの、双方の間のやり取りを明確に定義したもの

### 学んだこと

- WeakMap
Map との違いは、WeakMap のキーはプリミティブな値ではなくオブジェクトでなければならないこと
```javascript
let weakMap = new WeakMap();

let obj = {};

weakMap.set(obj, "ok"); // 正常に動作する (オブジェクトのキー)

// キーに文字列は使えません
weakMap.set("test", "Whoops"); // エラー, "test" はオブジェクトではないため
```
オブジェクトをキーとして使用し、そのオブジェクトへの参照が他にない場合、自動的にメモリとmapから削除される

WeakMapはキーや値を取得する方法は無い

- WeakMapのメソッド
weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key, value)
weakMap.has(key)
WeakMapのメソッドは上記のみ

- WeakSet
Setに似ているが、WeakSetへはオブジェクトのみ追加できる
オブジェクトは、別の場所から到達可能である間、Setに存在し、他の手段でそのオブジェクトが到達不可能になると、それらも削除される
Set同様、add, has, delete をサポートする


### 感想
WeakMapとMap、WeakSetとSetそれぞれの違いを間違えないように覚えておく。


## 5.9 Object.keys, values, entries
### 知らない単語
- 無し

### 学んだこと
- Object.keys, values, entries

通常のオブジェクトで使えるメソッド
Object.keys(obj)はキーの配列を返す
Object.values(obj)は値の配列を返す
Object.entries(obj)は引数に与えたオブジェクトが所有する、文字列をキーとした列挙可能なプロパティの組[key, value]からなる配列を返す

使用例、下記のコードがあったとして、
```javascript
let user = {
  name: "John",
  age: 30
};
```
Object.keys(user)を使うと[name, age]が返ってくる
Object.values(user)を使うと["John", 30]が返ってくる
Object.entries(user)を使うと[ ["name","John"], ["age",30] ]が返ってくるようになっている


### 感想
前のチャプターで、map.keys(), map.values(), map.entries()などを学んだが、Object.keys(user)、Object.values(user)、Object.entries(user)と似ているので、細かな違いをしっかり理解しておく。

## 5.10 分割代入
### 知らない単語
- アンパックとは
    - タプルを作成することを、「複数の値を1つのタプルにまとめる」という意味で「タプルのパック」と呼ぶことがある、これに対して、タプルに格納されている要素の一つ一つを別々の変数へ代入することもできるが、これを「アンパック」と呼ぶ

- タプルとは
    - 複数のデータの組み合わせから構成されているデータを表現する場合に使用するオブジェクト

### 学んだこと

- Array の非構造化

配列を変数に分割する方法の例
```javascript
// 姓と名の配列
let arr = ["Bill", "Smith"]

// 分割代入
// sets firstName = arr[0]
// and surname = arr[1]
let [firstName, surname] = arr;

alert(firstName); // Bill
alert(surname);  // Smith
```
配列要素の代わりに変数を扱うことができる
splitや配列を返すメソッドと組み合わせる事もできる

- 残り ‘…’

３つのドット "..." を使用して “残り” を取得するパラメータを１つ追加できる
```javascript
let [fruits1, fruits2, ...rest] = ["apple", "banana", "grapefruit", "lemon"];

// restは３つ目の項目からの配列である
alert(fruits1); // apple
alert(fruits2); // banana
alert(rest[0]); // grapefruit
alert(rest[1]); // lemon
alert(rest.length); // 2
```
restを入れず、alert(fruits1)、alert(fruits2)のみであれば、後ろの項目は項目は省略される


- デフォルト値

代入する変数の数よりも配列の要素数のほうが少ない場合、不足分はundefinedと判定される
```javascript
let [fruits1, fruits2] = [];

alert(fruits1); // undefined
alert(fruits2); // undefined
```

- 分割代入はオブジェクトでも動作する
```javascript
let {prop : varName = default, ...rest} = object
```
これはプロパティ prop が変数 varName に代入され、もしこのようなプロパティが存在しない場合には default が使われることを意味する

### 感想
オブジェクトや関数が関わっている時の書き方や処理が難しいので混乱しないようにする。

## 5.11 日付 と 時刻
### 知らない単語
- タイムスタンプとは
    - インターネット上の取引や手続き等が行われた時刻や電子文書の存在した日時を証明するサービス

### 学んだこと
JavaScriptでの日付と時刻はDateオブジェクトで表現する
日付だけ、時刻だけを作ることはできない

- 作成
Dateオブジェクトを作るには、new Date()を使用する

new Date()
引数なしだと現在の日付と時刻で Date オブジェクトを作成する
```javascript
let 　time = new Date();
alert( time ); // 現在の日時を表示
```

new Date(milliseconds)
Jan 1st of 1970 UTC+0 (1970年 1月1日 UTC+0) からの経過したミリ秒(秒の1/1000)に等しい時間をもつ Date オブジェクトを作る
```javascript
// 0 は 01.01.1970 UTC+0 を意味します
let Jan01_1970 = new Date(0);
alert( Jan01_1970 );

// 今 24 時間を追加しました, 02.01.1970 UTC+0 になります
let Jan02_1970 = new Date(24 * 3600 * 1000);
alert( Jan02_1970 );
```
1970年初めから経過したミリ秒の数値は タイムスタンプ と呼ばれる


- dateコンポーネントへのアクセス

その他、関係するメソッド
getFullYear()は年を取得する(4桁)
getMonth()は月を取得する、0から11。
getDate()は1から31の月と日を取得する
getHours(), getMinutes(), getSeconds(), getMilliseconds()
対応する時刻の構成要素を取得する

- 日付の構成要素を設定する
日付/時刻の構成要素をセットするメソッド
setFullYear(year [, month, date])
setMonth(month [, date])
setDate(date)
setHours(hour [, min, sec, ms])


### 感想
日付と時刻だけで多くのメソッドがあるので、適切に使用できるよう、色々試していきたい。
JavaScriptでのタイムスタンプは秒ではなく、ミリ秒だという事は重要なので忘れないようにしたい。

## 5.12 JSON メソッド, toJSON
### 知らない単語
- デコードとは
    - 何らかの規約に従って符号化されたデータを、元の形式に戻す処理

- シリアライズ
    - 複数の要素を一列に並べる操作や処理の事

### 学んだこと
JSON はほとんどのプログラミング言語に対して、自身の独立した標準とライブラリを持つデータ形式

JSONが対応するデータはオブジェクト、配列、文字列、数値、真偽値、nullがある

- JSONの書き方

JSONは {} の中にキーと値をコロンで区切って記述する
キーは必ずダブルクォーテーションで囲む必要があり、シングルクォーテーションだとエラーになる

{“key1” : “value1”, “key2” : “value2”}など


- JSON文字列 → オブジェクトへの変換

json_strがJSON文字列で、これをJSON.parse()に渡すことでオブジェクトに変換される
通常のオブジェクトの扱いと同じで、ドットで繋げながら取得したい要素にアクセスする
```javascript
let json_str = '{"id":1, "name":"tanaka", "attribute":{"gender":"male", "phone_number":"xxxxxxxxxxx", "birth":"1991/01/01"}}';
var obj = JSON.parse(json_str)
console.log(obj.name) //tanaka
console.log(obj.attribute.birth) //1991/01/01
```
このようになる

### 感想
JSONは様々な言語で使われていると思うので、他の言語を勉強した時にも活かせるよう理解を深めておく。


# 最後に
この章の中ではJSONが1番難しい。オブジェクトはJSONへの変換用メソッド「toJSON」があったり、JSON.stringifyは利用可能なら自動で呼び出したりと、それぞれの役割を正しく覚える事が重要である。