モダンJavaScript基本構文をまとめ（後半）

# モダンJavaScript基本構文をまとめ（後半）

（前半はこちら）=>｛https://qiita.com/dende-h/items/a63ffeca056aabd7aa58｝

まとめたのは配列とオブジェクトの定義や操作に関わるもの。

使いこなすとcodeが読みやすくなるが、**知らないと読めない**。

うまい使いどころに早く慣れたい。

## 分割代入-配列-

### const [ [変数名], [変数名],[変数名] ] = オブジェクト名

イメージとしては配列中身に対して、それぞれに先に変数を充てる感じ。･･･（1）

書き方も簡単。数の多い配列だと、後半の**スプレッド構文**と一緒に使うことが多いかも。

```jsx
//分割代入

//配列を用意した場合
const animeList = [
  "氷菓",
  "新世界より",
  "シンフォギア",
  "PSYCHO-PASS",
  "Charlotte"
];

//従来
const animeA = animeList[0];
const animeB = animeList[1];
console.log(animeA); //氷菓
console.log(animeB); //新世界より

//分割代入を利用･･･（1）
const [anime0, anime1, anime2, anime3, anime4] = animeList;
console.log(anime0, anime1, anime2, anime3, anime4);
//氷菓　新世界より シンフォギア　PSYCHO-PASS　Charlotte

//変数を宣言するときに[]で囲むことによって、左から順番に変数に代入できる
//取り出す時は変数名で配列の利用ができる
```

## 分割代入-オブジェクト-　（オブジェクトの省略記法）

### const { [プロパティ名], [プロパティ名] } = オブジェクト名

オブジェクトでも配列同じように分割代入が使える。･･･（2）

プロパティ名のみで中身を使えるようになるので、コードの冗長化を防げる。

また**プロパティの変数名を変更することもできる**・・・（3）

### オブジェクトの省略記法

**省略記法**はオブジェクトのプロパティ名と変数名が一致するとき、プロパティ名のみに省略できる書き方。･･･（4）

```jsx
//オブジェクトを用意した場合
const user = {
  name: "おかだ　としお",
  age: 60
};

//従来
const userName = user.name;
const userAge = user.age;
console.log(userName, userAge); // おかだ　としお　60

//分割代入を利用･･･（2）
const { name, age } = user;
console.log(name, age); // おかだ　としお　60
//オブジェクトの場合変数宣言のときに{}で囲む
//一致するプロパティ名で取り出すことができる

//オブジェクト省略記法･･･（4）
const name1 = "庵野秀明";
const name2 = "宮崎駿";

const animeter = {
  name1,      // name1:name1と書いているのと同じ
  name2       // name2:name2と書いているのと同じ
};
//プロパティ名と変数名が一致している場合省略可能

//変数名の変更･･･（3）
const { name1: newNmae1, name2: newName2 } = animeter;
console.log(newNmae1, newName2); //庵野秀明　宮崎駿
/** すでに使われている変数名の場合変数宣言の際に【プロパティ名：新しい変数名】
 *で新しい変数名で分割代入を利用できる
 */
```

## デフォルト値

分割代入で変数を定義する際や、関数の引数に対してデフォルトの値を設定しておくことができる。・・・（5）（6）

その値が存在しなければデフォルト値が勝手にはいるので、**if文などを使って制御しなくてもよい**。これは楽。

```jsx
//デフォルト値プロパティが存在しない場合のデフォルト値を設定できる
const animeter = {
  name1,      
  name2       
};
const { name3, name4 = "新海誠" } = animeter;　//･･･（5）
console.log(name3, name4); //　undifained , 新海誠
//プロパティに存在しないが、分割代入の際にデフォルト値を設定するとその値で使える。

//関数の引数にデフォルト値を設定する
const filmDirector = (name = "細田守") => {　　　//･･･（6）
  return console.log(`サマーウォーズの監督は${name}です`);
};

filmDirector();　　//サマーウォーズの監督は細田守です
//引数がなくてもデフォルトに設定した値が入る
```

## スプレッド構文-配列-

### 配列名やオブジェクト名の前に【...】を付ける・・・（7）（8）

スプレッド構文同士の組み合わせで新たな配列にすることも可能・・・（9）

配列やオブジェクトを使う際のコードの冗長化を防ぎ、**コピーする時にも役に立つ**便利なやつ。

うまく使えばコード書く量がぐっと減る。

```jsx
//スプレッド構文
//配列の値が順番に評価される
console.log(...animeList);　//・・・（7）
//氷菓 新世界より シンフォギア PSYCHO-PASS Charlotte

//分割代入の際、配列の一部を新しい配列としてまとめる
const animeList2 = [
  "まどかマギカ",
  "魔法少女育成計画",
  "結城友奈は勇者である",
  "六花の勇者",
  "灼眼のシャナ"
];
const [anime5, anime6, ...animes] = animeList2;
console.log(animes);
//["結城友奈は勇者である", "六花の勇者", "灼眼のシャナ"]
const [...animes2] = animeList2;　//・・・（8）
console.log(animes2);
//["まどかマギカ", "魔法少女育成計画", "結城友奈は勇者である", "六花の勇者", "灼眼のシャナ"]
const animeList3 = [...animes, ...animes2];　//・・・（9）
console.log(animeList3);
/**["結城友奈は勇者である", 
　*"六花の勇者", 
　*"灼眼のシャナ", 
　*"まどかマギカ", 
　*"魔法少女育成計画", 
　*"結城友奈は勇者である", 
　*"六花の勇者", 
　*"灼眼のシャナ"]
　*/
```

## スプレッド構文-オブジェクト-

### **プリミティブ型とオブジェクト型の値の持ち方の違い**

プリミティブ型は変数自体が値を持つ

オブジェクト型は**参照値をもつ**のでコピーの際に注意が必要・・（10）（11）

```jsx
//オブジェクトのコピーに使う
const obj1 = {
  character: "立花響",
  cv: "悠木碧"
};

const obj2 = obj1;
obj2.cv = "茅野愛衣";
console.log(obj1); //{character: "立花響", cv: "茅野愛衣"}
console.log(obj2); //{character: "立花響", cv: "茅野愛衣"}
//上記のようにコピーした場合obj2の中身を変更するとobj1の値も変わってしまう・・・（10）

const obj3 = {
  character: "暁切歌",
  cv: "茅野愛衣"
};
const obj4 = { ...obj3 };
obj4.cv = "水瀬いのり";
console.log(obj3); //{character: "暁切歌", cv: "茅野愛衣"}
console.log(obj4); //{character: "暁切歌", cv: "水瀬いのり"}
//スプレッド構文でコピーした場合中身を変更しても影響を与えない・・・（11）

//配列のコピーの際も同様。元の配列に影響を与えないでコピーできる。
const animeList4 = [...animeList3];
animeList4[0] = "ドラゴンボール";
animeList4[1] = "スラムダンク";
animeList4[2] = "幽遊白書";

console.log(animeList4);
```

## 配列の処理-map関数-

### for文なしで配列の繰り返し処理ができる便利な関数。

第一引数に配列の要素、第二引数に配列の順番がはいり、それらに対しての処理を記述することで、その処理を配列全てに繰り返し適用してくれる。

処理したものを**新しい配列として定義**するので、上記のスプレッド構文や分割代入と一緒に利用するとかなり簡潔なコードでいろいろできる。

```jsx
//map関数
const animeList5 = animeList4.map((item, index) => {
  console.log(`要素：${item}`, `順番：${index}`);
  return `順番：${++index} タイトル：${item}`;
});
console.log(animeList5);
/**["順番：1 タイトル：ドラゴンボール",
 * "順番：2 タイトル：スラムダンク",
 * "順番：3 タイトル：幽遊白書",
 * "順番：4 タイトル：まどかマギカ",
 * "順番：5 タイトル：魔法少女育成計画",
 * "順番：6 タイトル：結城友奈は勇者である",
 * "順番：7 タイトル：六花の勇者",
 * "順番：8 タイトル：灼眼のシャナ"]
 *
 * map関数の引数に関数をいれることで、配列を順番に処理して新しい配列を生成できる
 * 自動で各要素にアクセスして繰り返し処理ができる
 * 中に書く関数の第一引数は配列の要素
 * 第二引数は何番目かを表す数値
 * 引数の省略も可能
 * */
const animeList6 = animeList.map(() => {
  return `好きなアニメ`;
});
console.log(animeList6);
//["好きなアニメ", "好きなアニメ", "好きなアニメ", "好きなアニメ", "好きなアニメ"]
//引数に何もなければreturnが要素の数だけ繰り返される

const animeList7 = animeList.map((item, index) => {
  console.log(item);

  switch (index) {
    case 0:
      return `${item}はやさしい学園ミステリー`;
      break;
    case 1:
      return `${item}は超大作SF`;
      break;
    case 2:
      return `${item}は歌うアクション`;
      break;
    case 3:
      return `${item}は近未来SFサスペンス`;
      break;
    case 4:
      return `${item}は異能学園もの`;
      break;
    default:
      break;
  }
});
console.log(animeList7);
/**["氷菓はやさしい学園ミステリー",
 * "新世界よりは超大作SF",
 * "シンフォギアは歌うアクション",
 * "PSYCHO-PASSは近未来SFサスペンス",
 * "Charlotteは異能学園もの"]
 *
 * 処理の中で分岐も可能。
 * for文で繰り返すよりわかりやすい
 *
 * */
```

## 配列の処理-filter関数-

### for文if文なしで配列の条件抽出ができる

mapは繰り返し処理に対して、こちらは**繰り返しの中から条件に合うものを抽出する関数**。

書き方はmapとほぼ同じ。returnの真偽値を判定して、Trueになる値を抽出する。

```jsx
// filter
//配列を順番に処理して条件に一致する新しい配列を生成
const animeList8 = animeList.map((item, index) => {
  return ++index;
});

console.log(animeList8);

const animeList9 = animeList8.filter((item, index) => {
  return item % 2 === 1; //itemが奇数の場合
});
console.log(animeList9); //[1, 3, 5]

const animeList10 = animeList7.filter((item, index) => {
  return ++index % 2 === 0; //indexに+1してそれが偶数の場合
});
console.log(animeList10);
//["新世界よりは超大作SF", "PSYCHO-PASSは近未来SFサスペンス"]

/**
 * 配列の中で条件にあったものを絞り込みできる
 * 上記mapとfilterを使うことでfor文を使わずに配列の繰り返し処理ができる
 */
```

## Null合体演算子

【??】の左側が**null**もしくは**undeined**だったときに、右側を評価する。

これらを**nullishと表現する**

【**ES2020】の新しい記法**

【０】や【””】のような空文字は**nullish**ではないので評価されない。

やはり分岐文を省略できる。

```jsx
//Null合体演算子
//記号「??」を使う。null/undeinedで評価を行う
const text = "値がNullです";
let nullish = null;

let message = nullish ?? text;
console.log(message); //値がNullです

nullish = "";
message = nullish ?? text;
console.log(message); // ""
```