JavaScriptの基本について

## JavaScriptとは

JavaScript（通称 JS）は、Web開発で主にブラウザ上の動作を制御するインタープリター型のプログラミング言語です。ボタンのクリックなどのユーザーのアクションに応じて、HTMLの内容やCSSのスタイルを動的に変更できます。
JSは豊富なライブラリーにより、フロントエンドからバックエンドまで作ることができるフルスタック言語です。

## 基本構造
## 変数
- 1つの変数につき、1つの値を代入することができます。
- 変数を定義することを変数宣言と言います。
- JSでは、変数の宣言には、var,let,constの三つがあります。
	- varは、現在は使われていません。
	- letは、再代入が可能な変数宣言です。
	- constは、再代入ができない変数宣言です。

:::note warn
警告
- var は ブロックスコープを持たない ため、意図しない変数の上書きが発生しやすい。
- var は 巻き上げ によって、宣言だけが関数の先頭に移動 し、思わぬ undefined が発生しやすい。
- varは、意図しない上書きや思わぬ undefined が発生しやすいため、非推奨です。
:::

```JavaScript
let a = 'Hello';
console.log(a) //Helloが出力

a = 'Hello World'
console.log(a) //Hello Worldが出力


const b = "Hello";
console.log(b) //Helloが出力

b = "Hello World";
console.log(b) //エラーが起こる
```

## 四則演算
### 四則演算の例
```JavaScript
// 2つの数字を用意
let a = 10;
let b = 3;

// 四則演算の計算
let sum = a + b;   // 加算
let diff = a - b;  // 減算
let product = a * b; // 乗算
let quotient = a / b; // 除算

// 計算結果を表示
console.log("a =", a, ", b =", b); //a = 10 , b = 3が出力
console.log("足し算 (a + b) =", sum); //足し算 (a + b) = 13が出力
console.log("引き算 (a - b) =", diff); //引き算 (a - b) = 7が出力
console.log("掛け算 (a * b) =", product); //掛け算 (a * b) = 30が出力

```

- また、四則演算は数字だけでなく、`+`だけは文字にも利用することができます。
### 文字の場合の例
```JavaScript
let str1 = "Hello";
let str2 = "World";

console.log(str1 + " " + str2); //Hello Worldが出力

```

##  データ型と演算子
### データ型
- JSは動的型付け言語です。
- 動的型付け言語とは、変数を宣言するときに型を指定せず、代入した値によって自動的に型が決まります。
**`typeof()`を使用するとデータ型を確認することができます。**

```JavaScript
const num = 123;
const str = "Hello World";
const bool = true

console.log(typeof(num)); //numberが出力
console.log(typeof(str)); //stringが出力
console.log(typeof(bool)); //booleanが出力
```

- データ型
    - 文字列:string
    - 数値：number
    - ブーリアン:boolean

:::note warn
警告
- 言語ごとで型が異なるため注意。 
:::


### 演算子
#### 算術演算子 例

| 演算子 | 意味            |
| --- | --- |
|+|	数値の加算|
|-|	数値の減算|
|*|	数値の乗算|
|**|	数値のべき乗	|
|/|	数値の徐算	|
|%|	数値の剰余　|
|++|	1増やす（インクリメント）|
|--|	1減らす（デクリメント）|

```javascript
let a = 10;
let b = 3;

console.log(a + b);  // 13  （加算）
console.log(a - b);  // 7   （減算）
console.log(a * b);  // 30  （乗算）
console.log(a ** b); // 1000（べき乗）
console.log(a / b);  // 3.333...（除算）
console.log(a % b);  // 1   （剰余）

let x = 5;
x++;  // 1増やす
console.log(x); // 6

x--;  // 1減らす
console.log(x); // 5

```

#### 比較演算子 例
| 演算子 | 意味  |
| --- | --- |
| ==  | 等しい（型変換あり）    |
| === | 厳密に等しい（型も比較）  |
| !=  | 異なる（型変換あり）    |
| !== | 厳密に異なる（型も比較）  |
| >   | より大きい         |
| <   | より小さい         |
| >=  | 以上            |
| <=  | 以下            |

```javascript
let num1 = 5;
let num2 = "5";

console.log(num1 == num2);  // true  （型変換ありの比較）
console.log(num1 === num2); // false （厳密比較、型も違うため false）

console.log(num1 != num2);  // false （型変換ありの比較）
console.log(num1 !== num2); // true  （厳密比較）

console.log(num1 > 3);  // true  （5 は 3 より大きい）
console.log(num1 < 3);  // false （5 は 3 より小さくない）
console.log(num1 >= 5); // true  （5 は 5 以上）
console.log(num1 <= 4); // false （5 は 4 以下ではない）

```

#### 代入演算子  例

| 演算子 | 意味  |
| --- | --- |
|=|	変数などに値を代入|
|+=|	左辺の値に右辺の値を加算したものを代入|
|-=|	左辺の値から右辺の値を減算したものを代入|
|*=|	左辺の値に右辺の値を乗算したものを代入|
|/=|	左辺の値を右辺の値で除算したものを代入|
|%=|	左辺の値を右辺の値で除算した余りを代入|

```javascript
let value = 10;

value += 5; 
console.log(value); // 15

value -= 3;  
console.log(value); // 12

value *= 2;  
console.log(value); // 24

value /= 4;  
console.log(value); // 6

value %= 5;  
console.log(value); // 1

```

#### 論理演算子 例

| 演算子 |意味|
| --- | --- |
| && | AND（かつ） → 両方が `true` のとき `true` | 
| \|\| | OR（または） → どちらかが `true` なら `true` |
| ! | NOT（否定） → `true` を `false` に、`false` を `true` にする |

```javascript
let a = true;
let b = false;

console.log(a && b); // false
console.log(a || b); // true 
console.log(!a);     // false
console.log(!b);     // true 

// 実用例：年齢制限
let age = 20;
let hasID = true;
console.log(age >= 18 && hasID); // true（年齢が 18 以上かつ身分証ありなら OK）

// 実用例：ログインチェック
let username = "user";
let password = "";
console.log(username && password); // ""（空文字は false 相当）

```

:::note warn
警告
- 他にも演算子はあります。
:::

## 条件分岐
### if文
- if (条件) {条件を満たした場合の処理;}
-  条件がfalseの場合は、{}内の処理を実行しません
```javascript
const age = 22;

if (age >= 18) {
    console.log("成人");
}
// 出力結果：成人
```

### if~else文
- if(条件){条件を満たした場合の処理;}
- else{条件を満たさなかった場合の処理;}

```javascript
const age = 17;

if (age >= 18) {
    console.log("成人");
} else{
    console.log("未成人");
}
// 出力結果：未成人
```

### if~else if文
- if(条件A){条件Aを満たした場合の処理;} 
- else if(条件B){条件Bを満たした場合の処理;} 
- else{条件を満たさなかった場合の処理;}
```javascript
const age = 0;

if (age >= 18) {
    console.log("成人");
} else if (age == 0) {
    console.log("幼児");
} else{
    console.log("未成人");
}
// 出力結果：幼児
```

## 繰り返し処理
- 条件を満たすときに繰り返し処理を行います
- 条件式には、いろいろありますが今回は`for文`と`while文`を見ていきます。

### for文
- 繰り返し回数が決まっているときに使います。
- カウンターがある場合（i++ など）に適しています。
```javascript
for (let i = 1; i < 10; i++){
    console.log(i); 
}
//出力結果
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
```

### while
- 条件が true の間、繰り返し続けるときに使います。
- いつ終わるか分からないときに適しています。
```javascript
let i = 1;

while (i < 10){
  console.log(i); 
  i = i * 2
}
//出力結果
// 1
// 2
// 4
// 8

```

## 配列
### 配列の宣言と初期化
- 配列は [] を使って宣言します
```javascript
let arr = [1, 2, 3, 4, 5];  // 数字の配列
let fruits = ["Apple", "Banana", "Cherry"];  // 文字列の配列
let mixed = [1, "Hello", true];  // 異なる型も格納可能
```
### 配列の要素にアクセス
- 配列の各要素には、インデックス（添字） を使ってアクセスできます。
- インデックスは 0 から始まる ので、1番目の要素は 0 番になります。
```javascript
let colors = ["Red", "Green", "Blue"];

console.log(colors[0]); // Red（1番目の要素）
console.log(colors[1]); // Green（2番目の要素）
console.log(colors[2]); // Blue（3番目の要素）

```
### 配列の要素を変更
- 配列の特定の要素を変更するには、インデックスを指定して代入します。
```javascript
let numbers = [10, 20, 30];
numbers[1] = 25;  // 2番目の要素を変更
console.log(numbers); // [10, 25, 30]
```

### 配列の操作
#### 要素の追加
- push() → 配列の 末尾 に追加
- unshift() → 配列の 先頭 に追加
```javascript
let fruits = ["Apple", "Banana"];
fruits.push("Cherry");  
fruits.unshift("Mango"); 
console.log(fruits); // ["Mango", "Apple", "Banana", "Cherry"]
```
#### 要素の削除
- pop() → 末尾 の要素を削除
- shift() → 先頭 の要素を削除
```javascript
let numbers = [1, 2, 3, 4];
numbers.pop();  // [1, 2, 3]
numbers.shift(); // [2, 3]
console.log(numbers); // [2, 3]
```

### 特定の要素の追加・削除
- splice() メソッドを使うと、配列の 特定の位置 にある要素を削除・追加できます。
- array.splice(開始インデックス, 削除する要素数, 追加する要素1, 追加する要素2, ...);
-  開始インデックス → 変更を開始する位置（0から始まる）
-  削除する要素数 → 指定した位置から何個の要素を削除するか（0を指定すると削除しない）
-  追加する要素（省略可）→ 指定した位置に追加する新しい要素
#### 追加
```javascript
let fruits = ["Apple", "Banana", "Cherry"];

// インデックス 1（2番目の要素）に "Orange" を追加（削除はしない）
fruits.splice(1, 0, "Orange");

console.log(fruits); // ["Apple", "Orange", "Banana", "Cherry"]

```
#### 削除 
```javascript
let arr = [1, 2, 3, 4, 5];
arr.splice(2, 1);  // 3 を削除
console.log(arr); // [1, 2, 4, 5]

```

### 配列のループ処理
配列の要素数、繰り返しするには`forループ`や`map()メソッド`があります。
**for ループ**
```javascript
let scores = [80, 90, 75];

for (let i = 0; i < scores.length; i++) {
  console.log(scores[i]);
}
// 出力:
// 80
// 90
// 75
```
**map()メソッド**
```javascript
let numbers = [1, 2, 3, 4, 5];

const a = numbers.map((num) => {
    return num * 2; // 各要素を2倍にする
});

console.log(a); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5]（元の配列はそのまま）

```
## 関数
- 関数を作ることを「関数を定義する」と言います。
関数の定義方法
- 関数宣言（基本）
- 関数式（無名関数とアロー関数）　※アロー関数が一般的
### 基本的な関数
- 関数の定義：function 関数名(引数名) {実行したい処理;};
- 関数の呼び出し：関数名();
```javascript
function sum (a,b) { //関数定義
    return a + b;
};
let result = sum(2,4);//関数の呼び出し
console.log(result); //6
```
### 式による関数定義（アロー関数）
- 式による関数定義とは、関数を変数に代入したもの
- 変数に代入して、式として関数を定義する
- 名前の通り矢印の=>を用いて関数を定義する。functionの代替。
- 関数定義：(引数) => {実行したい処理};
- 関数の呼び出し：変数名();
```javascript
const sum = (a,b) => { //関数定義
    return a + b;
};
let result = sum(2,4);//関数の呼び出し
console.log(result); //6
```
> [!WARNING]
>- return で関数の結果の値を返しています。
## オブジェクト
- オブジェクト とは、複数のデータを「キー」と「値」のセットで管理するもの です。
### 基本
```javascript
let person = {
    name: "太郎",    // 名前（キー: "name", 値: "太郎"）
    age: 25,        // 年齢（キー: "age", 値: 25）
    city: "東京"     // 住んでいる場所（キー: "city", 値: "東京"）
};

console.log(person.name);  // "太郎"（オブジェクトの値を取得）
console.log(person.age);   // 25
console.log(person.city);  // "東京"

```

### オブジェクトの値を変更する
- オブジェクトの中のデータ（プロパティ）は 後から変更 できます。
```javascript
person.age = 26;  // 年齢を変更
console.log(person.age);  // 26

```
- 新しいプロパティを追加することもできます。
```javascript
person.job = "エンジニア";  // 新しいプロパティを追加
console.log(person.job);  // "エンジニア"

```
### オブジェクトのループ処理
オブジェクトの中のすべてのデータを取り出すときは`for...in`を使います。
```javascript
for (let key in person) {
    console.log(key + ": " + person[key]);
}
//出力結果
//name: 太郎
//age: 26
//city: 東京
//job: エンジニア
```

## Promise
- Promise（プロミス）は、「非同期処理の結果を表すオブジェクト」 です。
- 処理の順序に「お約束」を取り付けることができるものです。
- Promiseでの状態
    - pending（保留）	まだ結果がわからない（処理中）
    - fulfilled（成功）	非同期処理が 成功 して結果が得られた
    - rejected（失敗）	非同期処理が 失敗 した

### Promiseの基本文
```javascript
const promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("成功しました！"), 1000);
});
```

### async/await を使ったPromise例
```javascript
async function fetchData() {
    try {
        let result = await promise;
        console.log(result);  // 成功しました！
    } catch (error) {
        console.log(error);  // 失敗しました…
    }
}

fetchData();
```
- Promiseは、APIからデータを取得や遅延処理でよく使われます。
### APIからデータを取得
```javascript
const request = () => {
    const url = "https://jsonplaceholder.typicode.com/todos/1";//例
    fetch(url, {
      method: "GET",//メゾットの指定
      headers: {
        "Content-Type": "application/json",//おまじないみたいなもの
      },
    })
      .then((response) => {
        if (!response.ok) {
          throw new Error("ネットワーク応答が正常ではありません");
        }
        return response.json();//ここにレスポンスが返ってくる
      })
      .then((data) => {
        console.log("Success:", data);
      })
      .catch((error) => {
        console.error("Error:", error);
      });
  };
```

### 遅延処理
```
function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function run() {
    console.log("3秒待ってください...");
    await delay(3000);
    console.log("3秒後に実行！");
}

run();
```