JavaScriptの学び直し。

# 変数・定数
- 数値から始めてはいけないです。

# スコープ
- グローバルスコープ
どこからでも参照可能です。

- ローカルスコープ
ブロック内だけで参照可能です。

# データ型

## 文字列→数値変換
`Number()`を使用する。
## 数値→文字列変換
`String()`を使用する。

## 数値・文字列と配列・オブジェクトの違い
配列やオブジェクトでの更新は、「全体を変えずに、中の一部だけを変更する」ことです。
そのため、constで宣言した値は更新できないですが、配列（オブジェクトも）は更新することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/6e314f39-b833-4351-b1c8-08f430715f91.png)

そのため、代入時の挙動も異なります。
数値や文字列はバックアップの値を別の定数名で保持しておくことは可能ですが、配列やオブジェクトは、参照の方法が下記のように異なるため、バックアップをとっておくことはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/eb159454-63e4-4dc2-8b64-b0d2a539a7b3.png)

配列のバックアップを取りたい場合は、スプレッド構文を使用しましょう。
```JavaScript
const nums = [10, 20, 30];
const numsBackup = [...nums];
nums[0] = 99;
console.log(nums);//[ 99, 20, 30 ]
console.log(numsBackup);//[ 10, 20, 30 ]
```


## 配列
```JavaScript
let fruits = ["りんご", "バナナ", "みかん"];
```
### 更新と再代入
#### 更新とは
**配列の中の「一部の値を変更する」こと！**
```JavaScript
fruits[1] = "キウイ";  // 2番目（index 1）をバナナ→キウイに変更
console.log(fruits);  // → ["りんご", "キウイ", "みかん"]
```
#### 再代入とは
**「変数にまったく新しい配列を入れ直すこと」です！**
```JavaScript
fruits = ["スイカ", "メロン"];
console.log(fruits); // → ["スイカ", "メロン"]
```
💡 ポイント：
- この時、元の配列（りんごたち）はまるごと消えて、別のものに置き換えられます！
- **定数で定義した配列には再代入することはできない**です！

## オブジェクト
- オブジェクトは、「名前（キー）」と「値」をセットで管理できるデータの形です。

💬 たとえるなら、「ラベル付きの引き出し」のようなもの！
→このオブジェクト person は、「名前」「年齢」「職業」というラベルを持つ情報がまとまってる感じ！
```JavaScript
let person = {
  name: "gonta",
  age: 30,
  job: "エンジニア"
};
```

:::note info
オブジェクトは配列と違い、要素の順番を保持していないので表示の時に定義した内容と異なる場合があるが気にしなくて良い。
:::

### オブジェクト値の取り出し方
**ドット記法**
```JavaScript
console.log(person.name); 
console.log(person.age);  
```

**ブラケット記法**
```JavaScript
console.log(person["job"]); // → "エンジニア"
```

### 値の更新・追加
- 更新
```JavaScript
person.age = 29;
```

- 追加
```JavaScript
person.hobby = "読書";
console.log(person.hobby); // → "読書"
```
- 削除
```JavaScript
delete person.job;
```

### オブジェクトの値に入れられるもの
| データ型                 | オブジェクトの値にできる？ | メモ           |
| -------------------- | ------------- | ------------ |
| 文字列 `String`         | ✅ OK          | よく使う         |
| 数値 `Number`          | ✅ OK          | OK！          |
| 真偽値 `Boolean`        | ✅ OK          | true / false |
| 配列 `Array`           | ✅ OK          | よく使う！        |
| オブジェクト `Object`      | ✅ OK          | ネストもできる      |
| 関数 `Function`        | ✅ OK          | メソッドとして使える   |
| `null` / `undefined` | ✅ OK          | 状態の表現などに便利   |
| Symbol               | ✅ OK（キーにも使える） | ちょっと上級者向け    |

### オブジェクトを配列に変換する
配列で使用できるメソッドは、オブジェクトに使用することはできません。
そのような場合、よくオブジェクトを配列に変換する`Object.entries`メソッドが使用されます。

```JavaScript
const scores = {
  math: 80,
  english: 90,
};

const entries = Object.entries(scores);
console.log(entries);
/*表示結果
[ [ 'math', 80 ], [ 'english', 90 ] ]
*/
```

### `null`と`undefined`の違い
#### `undefined` 
「未定義の値」でし。
```JavaScript
let a;
console.log(a); // → undefined
```
↑ 変数は作ったけど、中身をセットしてない時に`undefined`になる。

#### `null` 
「意図的に空な値」です。
```JavaScript
let user = null;
console.log(user); // → null
```
↑「この変数は今は空だけど、あとで何か入る」という意味で 自分で`null`をセットするのが一般的です。

#### 🧪 `null`と`undefined`は、型も異なります！
```JavaScript
typeof undefined // → "undefined"
typeof null      // → "object" ← これはJavaScriptの仕様上のバグと言われてるよ（歴史的な事情で残ってるだけ）
```
なので、正確に違いをチェックしたいときは `===` を使おう！

# 配列を操作するメソッド
## 追加・削除
| メソッド        | 意味        | どこに追加/削除？ | 戻り値      |
| ----------- | --------- | --------- | -------- |
| `push()`    | **後ろに追加** | 配列の最後     | 新しい配列の長さ |
| `pop()`     | **後ろを削除** | 配列の最後     | 削除された値   |
| `unshift()` | **前に追加**  | 配列の先頭     | 新しい配列の長さ |
| `shift()`   | **前を削除**  | 配列の先頭     | 削除された値   |

## `forEach`
配列の中の要素を1つずつ取り出して、全ての要素に繰り返し同じ処理を行うメソッドです。
引数は2つ受け取ることができます。
- 要素：配列の要素一つ
    `["りんご", "みかん", "バナナ"]`という配列の各要素一つずつがこの要素に格納されます。
- インデックス：取り出した要素のインデックス

```JavaScript
配列.forEach((要素, インデックス) => {...})
```

記載例もチェックしておきましょう。
```JavaScript
const fruits = ["りんご", "みかん", "バナナ"];

fruits.forEach((fruit, index) => {
  console.log(`${index + 1}番目のフルーツは ${fruit} です`);
});
/*表示結果
1番目のフルーツは りんご です  
2番目のフルーツは みかん です  
3番目のフルーツは バナナ です
*/
```

## `find`
- 条件式に合う1つ目の要素を配列の中から取り出すメソッドです。
- findメソッドは条件に合う要素が見つかった時に終了するので、**条件に合う最初の1つの要素しか取り出せません**。
    - なければ `undefined` を返します。
- 配列の要素がオブジェクトの場合もfindメソッドを使うことができます。

```JavaScript
const 結果の値 = 配列.find(function(要素, インデックス, 配列全体) {
  // 条件（true を返したときに見つかったと判断）
});
```
:::note warn
`find`メソッドでは`return`は必須です。
しかし、コールバック関数が単一の式で記述されているアロー関数（中括弧 {} を含まない）の場合、記載しなくても実質的には`return`されていることになります。
:::

## `splice`
配列から 要素を削除したり、追加したりできるメソッドです。
削除の場合は、戻り値は配列となります。

```JavaScript
配列.splice(開始位置, 削除する数, 追加する要素1, 追加する要素2, ...);
```

例を見て動きを確認しましょう。
```JavaScript

const scores = [70, 90, 80, 85];

scores.splice(2, 0, 77, 88);
// 値追加・削除0[70, 90, 77, 88, 80, 85]

const deleted = scores.splice(3, 1);
// 値削除0[70, 90, 77, 80, 85]
// deletedには削除した値で作成された配列[88]が入る

const deleted2 = scores.splice(2, 2, 30);
// 値削除する・30も追加する[70, 90, 30, 85]
// deleted2には削除した値で作成された配列[ 77, 80 ]が入る

console.log(deleted);
// [ 88 ]

console.log(deleted2);
// [ 77, 80 ]

console.log(scores);
// [ 70, 90, 30, 85 ]
```

## `join`
配列のすべての要素を、1つの**文字列**に結合するメソッドです。
- 区切り文字を指定しない場合はカンマ`,`区切りとなります。
- 区切り文字なしの場合は空文字`''`を指定します。
```JavaScript
配列.join(区切り文字);
```

例を見て動きを確認しましょう。
```JavaScript
const names = ['Taro', 'Jiro', 'Saburo'];

console.log(names.join('|'));
// 表示結果　Taro|Jiro|Saburo
```

## `split`
文字列を指定した区切り文字で区切って、**配列にするメソッド**です。

```JavaScript
文字列.split(区切り文字);
```

例を見ていきましょう。
1: 区切り文字で分割する場合
```JavaScript
const names = 'Taro|Jiro|Sabro';
console.log(names.split('|'));
// [ 'Taro', 'Jiro', 'Sabro' ]
```
2: 文字ごとに分割する場合
```JavaScript
const name = "さくら";
const chars = name.split("");

console.log(chars); // → ["さ", "く", "ら"]
```

## `filter`
記述した条件に合う要素のみを取り出して、**新しい配列を作成する**メソッドです。
`find`メソッドと同様に、配列の要素がオブジェクトの場合も`filter`メソッドを使うことができます。
```JavaScript
const fruits = ["りんご", "バナナ", "もも", "ぶどう"];

const filtered = fruits.filter(fruit => fruit.length === 3);

console.log(filtered); 
// → ["りんご", "もも", "ぶどう"]
```

## `map`
配列内のすべての要素に処理を行い、その戻り値から新しい配列を作成するメソッドです。
mapメソッドもこれまでのメソッドと同様に、配列のオブジェクト要素に対しても使うことができます。
```JavaScript
// 数字を2倍にする例
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(num => num * 2);

console.log(doubled);
// → [2, 4, 6, 8, 10]
```

:::note info
map は「元の配列の数だけ」処理をします。
そして、必ず新しい配列を作成します。
:::


# 演算
足し算の場合、どちらかが文字列だったら文字列に変換されるので注意する。
```JavaScript
console.log(50 + '20');
//5020と表示される
```

# 比較演算子
| 演算子   | 読み方（意味）     | 例           | 結果（true/false） | 備考              |
| ----- | ----------- | ----------- | -------------- | --------------- |
| `===` | 厳密に等しい      | `3 === '3'` | `false`        | 型も値も同じときだけtrue  |
| `!==` | 厳密に等しくない    | `3 !== 3`   | `false`        | 型か値が違えばtrue     |
| `>`   | より大きい       | `5 > 3`     | `true`         |                 |
| `<`   | より小さい       | `5 < 3`     | `false`        |                 |
| `>=`  | 以上（大きいか等しい） | `5 >= 5`    | `true`         |                 |
| `<=`  | 以下（小さいか等しい） | `3 <= 2`    | `false`        |                 |

※`==`（だいたい同じでOK）
この演算子は「型が違っても、中身が同じっぽければOKだよ！」というタイプです。
JavaScriptが自動で型を変換してくれるからです。（これを「**型変換**」といいます）。
```JavaScript
1 == '1' // → true（数値と文字列だけど、中身が「1」で同じだからOK）
0 == false // → true（JavaScript的には似たような意味と判断される）
null == undefined // → true（特別に同じとみなされる）
```

# 条件（三項）演算子
```JavaScript
条件 ? 真のときの値 : 偽のときの値;
```
イメージしやすいように、例も記載しておきます。
```JavaScript
const age = 20;
const result = age >= 18 ? '大人' : '未成年';

console.log(result); // → "大人"
```
:::note info
ifとの違い
- 条件演算子は、値に代入できる。
- `if`はあくまでも命令文なので、値に代入はできない。
:::

# 論理演算子

- `&&`: 両方がtrueならtrueになる
- `||`: どちらかがfalseならfalseになる（左がtrueなら、右は見ない）
- `!`: true/falseを逆にする

# 条件分岐
## `if`
- ある条件が**真（true）**なら、特定のコードを実行する

```JavaScript
if (条件) {
  // 条件がtrueのときに実行される処理
}
```

- `else`や`else if`も使用可能
```JavaScript
let score = 80;

if (score >= 90) {
  console.log("すごい！");
} else if (score >= 70) {
  console.log("がんばったね！");
} else {
  console.log("次はもっとがんばろう！");
}
```

## `switch`
- ひとつの値に対して「いくつかのパターンを比べて、条件に合ったものを選ぶ」ための文法です。
- caseは2行連続で記載することも可能です。

```JavaScript
switch (条件の値) {
  case 値1:
    // 値1だったときの処理
    break;
  case 値2:
    // 値2だったときの処理
    break;
  default:
    // どのcaseにも当てはまらなかったときの処理
    break;
}
```

**信号機の例**
```JavaScript
const color = prompt('Color?');

switch (color) {
  case 'red':
    console.log('Stop!');
    break;
  case 'yellow':
    console.log('Slow down!');
    break;
  case 'blue':
  case 'green':
    console.log('Go!');
    break;
  default:
    console.log('Wrong color');
    break;
}
```

# 繰り返し

## `for`文

```JavaScript
for (初期化; 条件; 更新) {
  // 繰り返したい処理
}
```
### 処理実行の順番
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/5255c8f6-9cf1-4c2e-9318-3c66cb0a44f8.png)


例：
```JavaScript
// for文を用いて、1から100までの数字を出力してください
for (let number=1; number<=100; number++){
  console.log(number);
}
```

## `while`
条件が`true`の間、処理を繰り返す繰り返し構文です。

```JavaScript
while (条件) {
  // 条件がtrueの間、ここが繰り返される
}
```

### `do while`
1回処理を実行してから条件をチェックします。
その条件がtrueなら、また繰り返します。
→最低1回は必ず処理が実行されるのが特徴です！
```JavaScript
do {
  // この中の処理が1回は必ず実行される
} while (条件);
```

# `break`と`continue`
- `break`: 反復処理から抜ける
- `continue`:それ以降の処理をスキップして**次の反復処理にうつる**

```JavaScript
for (let year = 1; year <= 30; year++) {
  amount *= 1.05;
  if (amount < 200) {
    continue;
  }
  if (amount > 300) {
    break;
  }
  console.log(`Year ${year}: ${amount}`);
}
```

# 関数
関数が`return`文を伴わずに終了した場合、その関数の戻り値は自動的に`undefined`になります。

## 宣言方法
### 関数宣言
- 関数の名前が必須となる。
- 定義より前でも呼び出すことが可能となる。
```JavaScript
function double(num) {
  return num * 2;
}
```
### 関数式（無名関数）
- 関数の名前は任意である。（名前のない関数を**無名関数**と呼ぶ）
- 定義したあとに呼び出さないと、実行することができない。
```JavaScript
const double = function (num) {
  return num * 2;
};
```

## アロー関数
```JavaScript
const greet = () => {
  console.log('こんにちは！');
}
```

## コールバック関数
- 引数に渡される関数をコールバック関数と呼びます。
- コールバック関数は、引数として受け取った関数を、特定の条件が満たされた時、またはある処理が完了した後に実行します。

```JavaScript
const cook = (callback) => {
  console.log("料理を始めます！");
  // 料理が終わった
  callback();  // コールバック関数を呼び出す
};

const sayDone = () => {
  console.log("料理ができました！");
};

cook(sayDone);
```

- `forEach`などのメソッドで、各配列の要素に対して実行する処理（中身）のこともコールバック関数と呼びます。
```JavaScript
const fruits = ["りんご", "バナナ", "もも"];

fruits.forEach((fruit, index) => {
  console.log(`${index + 1}: ${fruit}`);
});
```
👇🏻この中の、下記の部分がコールバック関数です。
```JavaScript
(fruit, index) => {
  console.log(`${index + 1}: ${fruit}`);
})
```
# 分割代入
配列やオブジェクトの中から、値を取り出して変数に代入することです。

- 配列
```JavaScript
const scores = [70, 90, 80, 85];
const [first, sec, thi, four] = scores;
console.log(first, sec, thi, four);
//70 90 80 85
```

- オブジェクト
```JavaScript
const scores = {
  taro: 88,
  jiro: 70,
  saburo: 90,
};
const { taro, jiro, saburo } = scores;
console.log(taro, jiro, saburo);
// 88 70 90
```

:::note warn
`[]`に代入しているので、配列が作成されると勘違いしがちですが、それぞれの変数に代入していることを覚えておきましょう。
:::

**よく使用される値の書き換えについて**
```JavaScript
let start = 'Tokyo';
let goal = 'Osaka';

[goal, start] = [start, goal];

console.log(start);// Osaka
console.log(goal);// Tokyo
```

## レスト構文
分割代入といっしょに使って、「残りの値を**まとめて**配列で受け取る」構文 です。
左辺で使われます。

- 配列で受け取る
```JavaScript
const fruits = ["りんご", "みかん", "バナナ", "ぶどう"];

const [first, second, ...rest] = fruits;

console.log(first);  // → "りんご"
console.log(second); // → "みかん"
console.log(rest);   // → ["バナナ", "ぶどう"]
```
- オブジェクトで受け取る
```JavaScript
const scores = {
  taro: 88,
  jiro: 70,
  saburo: 90,
};
const { taro, ...others } = scores;
console.log(taro); //88
console.log(others); //{ jiro: 70, saburo: 90 }
```

## スプレッド構文
要素を取り出して広げる構文です。
右辺で使われます。
- 配列で広げる
```JavaScript
const moreScores = [77, 80];
const scores = [70, 90, 80, 85, ...moreScores];
console.log(scores);

//[ 70, 90, 80, 85, 77, 80 ]
```

- オブジェクトで広げる
```JavaScript
const moreScores = {
  shiro: 77,
  goro: 88,
};
const scores = {
  taro: 88,
  jiro: 70,
  saburo: 90,
  ...moreScores,
};

console.log(scores);
// { taro: 88, jiro: 70, saburo: 90, shiro: 77, goro: 88 }
```

# DOM
ブラウザはHTMLを読み込むと、`DOMツリー`（`Nodeツリー`）に変換し、`DOMツリー`をもとに画面に描画しています。
そして、`JavaScript`ではこの`DOM`を操作することができます。
`DOM`を操作できるので、`HTML`を`JavaScript`から操作できるということになります。
例：
```HTML
<body>
  <h1>こんにちは！</h1>
  <p>今日もがんばろうね。</p>
</body>
```
↑上記HTMLは、
JavaScriptから下記のように操作できるようになります。↓
```JavaScript
const heading = document.querySelector("h1");
heading.textContent = "こんばんは！";
```

では、学んでいきましょう！

## DOMメソッド
### `document.querySelector('セレクタ')`
HTMLの中から「特定のセレクタを1つだけ選びたい」ときに使うメソッドです。
最初に見つかった1つだけ返し、戻り値はHTML要素オブジェクト（`HTMLElement`**オブジェクト**）です。
取得した要素に対して、`textContent`や`style`、`classList`などのプロパティやメソッドを使って操作できます。
マッチする要素が一つも見つからない場合は、`null`を返します。

```HTML
 <div class="box red">ボックス1</div>
 <p id="myParagraph">これは段落です。</p>
 <div class="box blue">ボックス2</div>
 <ul class="myList">
    <li>アイテムA</li>
    <li>アイテムB</li>
 </ul>
```

```JavaScript
 // 1. IDで要素を取得 (最も一般的で推奨される方法)
        const paragraph = document.querySelector('#myParagraph');
        console.log(paragraph); // <p id="myParagraph">これは段落です。</p>

// 2. クラス名で要素を取得 (最初に見つかるものだけ)
        const firstBox = document.querySelector('.box');
        console.log(firstBox); // <div class="box red">ボックス1</div> (redクラスのボックスが取得される)

// 3. タグ名で要素を取得 (最初に見つかるものだけ)
        const firstLi = document.querySelector('li');
        console.log(firstLi); // <li>アイテムA</li>

// 4. より複雑なセレクタ (最初に見つかるものだけ)
        // クラス名が"myList"のul要素の中にある最初のli要素
        const nestedLi = document.querySelector('ul.myList li');
        console.log(nestedLi); // <li>アイテムA</li>
```

### `document.querySelectorAll('セレクタ')`
HTMLの中から指定したCSSセレクタで、該当するもの全てを取得することができるメソッドです。
返り値は`NodeList`という配列に似たリストです。

`NodeList`は、
**✅インデックスでアクセスすることができます**
```JavaScript
document.querySelectorAll('li')[0].textContent = 'Changed!';
document.querySelectorAll('li')[1].textContent = 'Changed!';
document.querySelectorAll('li')[2].textContent = 'Changed!';
```

**✅`forEach`を使うことができます**
```JavaScript
document.querySelectorAll('.target').forEach((li) => {
    li.textContent = 'change';
  });
```

:::note warn
配列にとてもよく似ていますが、完全な配列ではありません。
また、`NodeList`は、取得した時点のスナップショットです。
取得後にHTMLドキュメント内で要素が追加・削除されても、この`NodeList`の中身は自動的には更新されません。
:::


### `addEventListener('イベントの種類',関数)`
「何らかの出来事（イベント）が発生したときに、特定の処理を実行するように設定する」ためのメソッドです。

```JavaScript
//キーが押された時、なんのキーが押されたのかp要素で表示する
document.addEventListener('keydown', (e) => {
  document.querySelector('p').textContent = e.key;
});
```

```JavaScript
//マウスを動かしたら、そのxy座標が画面に表示される
document.addEventListener('mousemove', (e) => {
  document.querySelector('p').textContent = `X: ${e.clientX} X: ${e.clientY}`;
});
```

### `textContent`
HTML要素の中の「テキスト（文字）」だけ取得したり、書き換えたりできるメソッドです。

#### 取得
```HTML
<p id="greeting">こんにちは！</p>
```

```JavaScript
const message = document.querySelector("#greeting");
console.log(message.textContent); // 👉 「こんにちは！」と表示される
```

#### 書き換え
```HTML
<p>Hello</p>
<button>OK!</button>
```

```JavaScript
document.querySelector('p').textContent=document.querySelector('button').textContent;
```
- `document.querySelector('button').textContent`で、ボタンの中の文字「OK」を取得している

:::note info
`textContent`で内容を書き換えると、元々その要素の中にあったHTMLタグはすべて消えて、指定したテキストに置き換わります。
:::

### フォーム系のDOMツリー操作
HTMLのフォーム要素が持っている現在の値を操作するには`.value`で指定します。
```JavaScript
document.querySelector('input').value
document.querySelector('select').value
```

### `classList`
HTMLの要素がもってる class（クラス名）を追加・削除・確認できるプロパティです。

#### `classList.add('クラス名')`
クラスを追加します。
```JavaScript
document.querySelector('p').classList.add('pink-bg', 'red-border');
```
- カンマ区切りで複数のクラスを指定できます。

#### `classList.remove`
クラスを削除します。
```JavaScript
document.querySelector('p').classList.remove('green-color');
```

#### `classList.contains('クラス名')`
指定したクラスが設定されているかチェックし、`true`または`false`で返す。
```JavaScript
document.querySelector('p').classList.contains('pink-bg')
```

#### `classList.toggle('クラス名')`
クラスをON/OFFで切り替えるメソッド。
- そのクラスが付いてなければ追加
- 付いていれば削除する
```JavaScript
document.querySelector('p').classList.toggle('pink-bg')
```

### `createElement`
JavaScript上で、新しいHTML要素を作り出すためのメソッドです。
WebページはたくさんのHTML要素（タグ）でできていますが、初期のHTMLにはない要素を、JavaScriptの力で後から追加したいときに使います。
`createElement`で要素を追加したあと、`textContent`や`appendChild`などで、中身を追加していきます。

:::note info
`createElement`で作られた要素は、オブジェクトと同じです。
`textContent`などは`createElement`で作られた要素（＝オブジェクト）のプロパティになります。
また、`let`ではなく`const`で定義することができます。
:::

```JavaScript
document.createElement('タグ名');
```

### DOMツリーを操作するメソッド
`createElement`で作成した要素は、DOMツリーに追加しないと画面に描画されません。
ここでは、DOMツリーに追加・削除などDOMツリーを操作できるメソッドについて紹介します。

#### `appendChild()`
指定した親要素の「子要素の最後」に、新しい要素を追加するためのメソッドです。
既にDOM上に存在する要素を `appendChild()`で移動させると、元の場所からは削除され、新しい場所（指定した親要素の最後）に移動します。

```JavaScript
親Node.appendChild（追加したい子要素）

//例
document.querySelector('ul').appendChild(liElement);
```

#### `insertBefore() `
指定した親要素の中の「特定の子要素の直前」に、新しい要素を挿入するためのメソッドです。
もし 基準となる子要素 を null に指定した場合、`insertBefore()`は`appendChild()`と同じように、親要素の最後に要素を追加します。 

```JavaScript
親Node.appendChild（追加したい子要素, 基準となる子要素）

//例
 document
    .querySelector('ul')
    .insertBefore(liElement, document.querySelector('#target'));
```

#### `remove()`
指定したHTML要素を、Webページ（DOMツリー）から完全に削除するためのメソッドです。
削除する要素に子要素がある場合、その子要素もまとめて一緒に削除されます。

```JavaScript
削除したい要素.remove();

//例
document.querySelector('#target').remove();
```

### 属性操作
`要素．同名のキーワード＝値`で上書きすることができます。

```JavaScript
<img src="dog.png">
⇩
document querySelector ('img').sre = 'cat.png';
```

```JavaScript
<a href="https://dotinstall.com">
⇩
document. querySelector ('a').href =
'https://256times.com'
```

基本的には上記で可能ですが、注意が必要な操作が3つあります。

#### 1.class
classに関しては、上記のように`.class`とすることはできません。
`classList.add`を使用しましょう。

#### 2.disabled/checked/selected
ブール値に関しては、`true`/`flase`のどちらかで設定しましょう。

#### 3.style
基本的には同じように設定できますが、**CSSプロパティ名**（font-size）などを細かく設定する必要があります。
```JavaScript
要素.style.CSSプロパティ名 = '値';
```

また、ハイフンは使用できないのでキャメルケースに変換する必要があります。
- `background-color`→ `backgroundColor`
- `font-size`→ `fontSize`

そして 必ず値を文字列として指定します。
```JavaScript
document.querySelector('p').style.fontSize = '24px';
```

**

主要なメソッドを紹介できたところで、少し古いメソッドも紹介していきます。

### `getElementById('id名')`
IDで1つの要素を取得できるメソッドです。

### `getElementsByTagName('タグ名')`・`getElementsByClassName('クラス名')`
タグ名（pとかdivとか）やclass属性でつけたクラス名から、複数の要素をまとめて取得できます。

:::note warn
戻り値は特殊なリストなので、インデックスでアクセスできたり、ループで回せたりしますが`ForEach`は使用できません。
:::

## イベントの種類
### マウス系
| イベント名         | 内容             |
| ------------- | -------------- |
| `'click'`     | クリックされたとき      |
| `'dblclick'`  | ダブルクリックされたとき   |
| `'mouseover'` | マウスが要素の上に乗ったとき |
| `'mouseout'`  | マウスが要素から外れたとき  |
| `'mousedown'` | マウスのボタンを押した瞬間  |
| `'mouseup'`   | マウスのボタンを離したとき  |

### キーボード系
| イベント名        | 内容                             |
| ------------ | ------------------------------ |
| `'keydown'`  | キーを押したとき（押しっぱなしでも発火）           |
| `'keyup'`    | キーを離したとき                       |
| `'keypress'` | キーを押したとき（※非推奨：今は`keydown`を使おう） |


### フォーム系
| イベント名      | 内容                      |
| ---------- | ----------------------- |
| `'submit'` | フォームが送信されたとき            |
| `'change'` | inputやselectの内容が変更されたとき |
| `'input'`  | 入力された瞬間（リアルタイム）         |
| `'focus'`  | 要素にフォーカスが当たったとき         |
| `'blur'`   | フォーカスが外れたとき             |


### その他
| イベント名                | 内容                       |
| -------------------- | ------------------------ |
| `'load'`             | ページや画像が読み込まれたとき          |
| `'scroll'`           | スクロールされたとき               |
| `'resize'`           | ウィンドウサイズが変わったとき          |
| `'DOMContentLoaded'` | HTMLの読み込みが完了したとき（画像など除く） |




# クラス
- Webサービスなどでは、オブジェクトをいくつも扱っています。
    - 例えばログインが必要なサービスでは、ユーザー（利用者）に関するデータ（オブジェクト）を用いています。
- 効率よくオブジェクトを作成していくための方法として、最初に「設計図」を用意する方法があります。
    - 例えばユーザーのデータをいくつも作成する場合、最初に「ユーザーを生成するための設計図」を用意し、その設計図をもとにユーザーのデータを生成していく、といったことができます。
- 「設計図」のことをJavaScriptでは「クラス」と呼びます。
    - たとえば「犬」というクラスを作ったら、そこから「ポチ」「コロ」みたいな具体的な犬（＝**インスタンス**）をいくつも作ることができます🐶
- クラスの戻り値はオブジェクトになります。

## インスタンス
- クラス（設計図）から生成したオブジェクト（データ）のことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/537939f5-44cf-4062-b6dd-f4f0ef4e88c5.png)
- オブジェクトを生成するための設計図を用意したら（クラスを定義できたら）、クラス（設計図）からオブジェクトを生成（データ）します。
- **クラスからオブジェクトを生成するには、「`new クラス名()`」とします。**
    - クラスから生成したオブジェクトは特別に**インスタンス**と呼びます。
- また、**`Animalクラス`のインスタンス**を`Animalインスタンス`と呼びます。

##  `constructor()`
**インスタンスが作られたときに実行される処理や関数、値や設定を追加するための機能**です。

## `this`
- **そのインスタンス自身のこと**です。
- コンストラクタの中で「`this.プロパティ名 = 値`」とすることで、**生成されたインスタンスにプロパティと値を追加することができます**。
- また、クラス内で値やメソッドを呼び出す時は`this.メソッド名`や`this.値`などとします。

:::note info
`this`は呼ばれた時に、呼び出しているインスタンスに置き換えられます。
:::


## メソッド
- そのインスタンスの「動作」のようなものです。
- メソッドは「挨拶をする」「値を計算する」などの処理のまとまりを表します。
```JavaScript
//Animalクラスを定義
class Animal {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  greet() {
    console.log("こんにちは");
  }
  
  info() {
    this.greet();
    console.log(`名前は${this.name}です`);
    console.log(`${this.age}歳です`);
  }
}

// catインスタンス生成
const cat = new Animal('レオ',4);
```
上記の`cat`インスタンスの中身は下記となります。
```JavaScript
Animal { name: 'レオ', age: 4 }
```
- 下記のようにオブジェクト指定で、中身を確認することもできます。
    - `cat.name`→レオ
    - `cat.age`→4

上記で`cat.info()`を実行すると結果は下記となります。
```JavaScript
こんにちは
名前はレオです
4歳です
```

:::note warn
`console.log(cat.info())`を実行すると、`undefined`も取得してしまうので、注意してください！
:::

## クラスの継承
- 「継承」とは、すでにあるクラスをもとに、新しくクラスを作成する方法のことです。
    - 例えば「`Animalクラス`」から「`Dogクラス`」を継承すると、「`Animalクラス`」の全ての機能を引き継いで、「`Dogクラス`」を作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/d91ee2bf-dbf7-4f93-9c8c-2c4cb03736dd.png)

```JavaScript
class Dog（新しいクラス名） extends Animal（継承元のクラス名）{
}
```
- 継承元となるクラスを親クラス、新しく作成するクラスを子クラスと呼びます。
- 継承して作成したクラスにも、これまでと同じようにメソッドを追加することができます。

:::note warn
子クラスで定義した独自のメソッドは、親クラスから呼び出すことはできません。
:::

### オーバーライド
- 親クラスと同じ名前のメソッドを子クラスに定義すると、子クラスのメソッドが優先して使用されます。
- 子クラスのメソッドが親クラスのメソッドを上書きしていることから、**オーバーライド**と呼ばれます。

#### コンストラクタのオーバーライド
- メソッドと同じように、コンストラクタもオーバーライドすることができます。
- ただし、コンストラクタをオーバーライドする際は1行目に「`super()`」と記述する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/652dbb9b-897a-406a-a657-5be9a6c70300.png)
- 子クラスのコンストラクタ内の「super()」では、その部分で親クラスのコンストラクタを呼び出しています。
    - そのため、親クラスのコンストラクタが引数を受け取る場合には、「`super`」の後ろの丸括弧「`( )`」に引数を渡す必要があります。
- 今回は親クラスのコンストラクタを呼び出したあとに、犬の種類を表す「`breed`」プロパティを追加しています。

## 静的フィールド・メソッド
`new`キーワードでインスタンスを生成することなく、クラスそのもの（クラス名）を通じて直接アクセスするメンバーのことを静的フィールド・メソッドと呼びます。
すべてのインスタンスで共有される共通のデータや、インスタンスとは直接関係ない処理を定義する際に使用します。

### 静的メソッド (Static Methods)
静的メソッドは、クラスのインスタンスではなく、クラスそのものから呼び出されるメソッドです。
#### 定義方法
メソッドの前に `static` キーワードを付けます。
```JavaScript
class クラス名 {
  static 静的メソッド名() {
    // 処理
  }
}
```
#### 呼び出し方
```JavaScript
クラス名.静的メソッド名();
```

:::note info
ポイント
- `new` 演算子を使わずに直接クラス名から呼び出せます。
- 静的メソッドの中から、インスタンスのフィールドやインスタンスメソッドに直接アクセスすることはできません。
- `this`は、その静的メソッドが属するクラス自体を指します。
:::

### 静的フィールド (Static Fields)
静的フィールドは、クラスのインスタンスではなく、クラスそのものに属する変数（プロパティ）です。
すべてのインスタンスで共通の値を持ちます。

#### 定義方法
プロパティ名の前に static キーワードを付けます。
```JavaScript
class クラス名 {
  static 静的フィールド名 = 初期値;
}
```

#### 呼び出し方
```JavaScript
クラス名.静的フィールド名;
```

:::note info
ポイント
- 静的メソッドの中から、同じクラスの他の静的フィールドや静的メソッドには `this.静的フィールド名` や `this.静的メソッド名()` でアクセスできます。（this がクラス自体を指すため）
:::

## `getter`/`setter`
`getter` と `setter` は、クラスのプロパティ（データの値）を読み取ったり、設定したりする際の「窓口」のようなものです。
直接プロパティにアクセスするのではなく、これらの特別なメソッドを通してアクセスすることで、様々なメリットが生まれます。

### `getter`
`getter`は、クラスのプロパティの値を「取得する」ための特別なメソッドです。
メソッドですが、プロパティのようにアクセスできます。

#### 定義方法
```JavaScript
class クラス名 {
  get プロパティ名() {
    // 値を返す処理
    return 値;
  }
}
```

#### 使い方
```JavaScript
const インスタンス = new クラス名();
インスタンス.プロパティ名; // メソッド呼び出しの () は不要
```

### `setter`
`setter`は、クラスのプロパティの値を「設定する」ための特別なメソッドです。
メソッドですが、プロパティに代入するように使えます。

#### 定義方法
```JavaScript
class クラス名 {
  set プロパティ名(値) {
    // 値を設定する際の処理
  }
}
```

#### 使い方
```JavaScript
const インスタンス = new クラス名();
インスタンス.プロパティ名 = 値; // メソッド呼び出しの () は不要
```

#### カプセル化
- ゲッターやセッターを使う場合、内部的に値を保持するプロパティは別の名前にするのが一般的で、慣習的に先頭に `_` を付けることが多いです。
- クラス外から変更できないようにするために`#プロパティ名`と先頭に `#` を付けることもあります。
    - こちらはメソッドにも使用することができます

`getter`/`setter`の使い方がわかるサンプルコードを作成しました。
```JavaScript
class User {
  // ① フィールドの宣言 (クラスプロパティ)
  name;
  _score; // 慣習的に、getter/setterの内部プロパティはアンダースコア(_)を付ける

  // ② コンストラクター
  // インスタンスが作られるときに、初期値を設定する場所
  constructor(name, score) {
    this.name = name;      // 引数で受け取ったnameをインスタンスのnameプロパティに設定
    this._score = score;   // 引数で受け取ったscoreをインスタンスの_scoreプロパティに設定
                           // ここでは直接_scoreに代入しているが、実際にはsetterを呼び出す方が堅牢
                           // (this.score = score; のようにすると、setterのバリデーションが働く)
  }

  // ③ getter (スコアの取得)
  // `user.score` のようにアクセスすると、このメソッドが実行される
  get score() {
    return this._score; // 内部の _score プロパティの値を返す
  }

  // ④ setter (スコアの設定)
  // `user.score = 値` のように代入すると、このメソッドが実行される
  set score(newVal) {
    // バリデーション（値が0未満または100より大きい場合）
    if (newVal < 0 || newVal > 100) {
      console.log('Invalid value!'); // エラーメッセージを出力
      return; // メソッドをここで終了し、値の変更を行わない
    }
    // バリデーションを通過した場合のみ、内部の _score プロパティを更新
    this._score = newVal;
  }
```

# インポート・エクスポート
## デフォルトエクスポート
デフォルトエクスポートは名前を自由につけられる特徴をもっています。

- エクスポート: `export default 定数名`
- インポート: `import 定数名 from "./ファイル名"`

🔹エクスポートファイル
```JavaScript
// hello.js
function sayHello() {
  console.log("こんにちは！");
}

export default sayHello;
```

🔹インポートファイル
```JavaScript
// main.js
import greet from './hello.js';

greet(); // → こんにちは！
```


### 注意点
- デフォルトエクスポートは1ファイル1つの値のみ使えます。
- 複数の値をエクスポートしたい場合は、「**名前付きエクスポート**」を用います。

## 名前付きエクスポート
1つのファイルで複数エクスポートすることができます。
デフォルトエクスポートでは好きな名前を使用できたのに対し、名前付きエクスポートは同じ名前を使う必要があります。
もし変更したければ、`as`を使用する必要があります。

- エクスポート `export { xxx,xxx };またはexport function xxx()`
- インポート `import { xxx } from '〜';`
    - as `import { formatDate as 別名 } from './〜';`

| 種類    | 名前付きエクスポート          | デフォルトエクスポート                 |
| ----- | ------------------- | --------------------------- |
| 関数    | ✅ `export function` | ✅ `export default function` |
| クラス   | ✅ `export class`    | ✅ `export default class`    |
| 変数（値） | ✅ `export const`など  | ✅ `export default 値`        |
※関数・クラス・値（定数やオブジェクトなど）すべて、名前付きエクスポートもデフォルトエクスポートもできます。

:::note info
相対パス：記述されているファイルからみた位置関係
:::

# パッケージ
JavaScriptの世界では、誰かが作った便利なプログラムがパッケージという形で公開されています。
また、JavaScriptの機能を使うことで、このパッケージを自分のプログラムの中に組み込んで使うことができます。
```JavaScript
import 別名 from 'パッケージ名';
```