新人研修チュートリアル②　JavaScript編

JavaScriptの基本的な文法と使用方法（ES6）

## 目次
1. [JavaScriptとは](#javascriptとは)
2. [変数](#変数)
3. [データ型](#データ型)
4. [条件分岐](#条件分岐)
5. [ループ処理](#ループ処理)
6. [関数](#関数)
7. [イベント処理](#イベント処理)
8. [配列の操作](#配列の操作)
9. [DOM操作](#dom操作)
10. [まとめ](#まとめ)

## 1. JavaScriptとは <a name="javascriptとは"></a>
JavaScriptは、Webページやアプリケーションのインタラクティブな動作を実現するためのプログラミング言語です。
ブラウザ上で動作し、HTMLやCSSと組み合わせてWebページを制御することができます。
JavaScriptは動的な要素の追加や削除、ユーザーの入力の処理、非同期通信などさまざまな機能を提供します。

![HTML・CSS・Javascriptの違い（例.顔マーク）](https://kosuke-space.com/wp-content/uploads/2021/06/HTML%E3%83%BBCSS%E3%83%BBJavascript%E3%81%AE%E9%81%95%E3%81%84%EF%BC%88%E4%BE%8B.%E9%A1%94%E3%83%9E%E3%83%BC%E3%82%AF%EF%BC%89-1024x576.png)※画像引用(https://kosuke-space.com/html-css-javascript)


## 2. 変数 <a name="変数"></a>
変数はデータを格納するための入れ物です。
JavaScriptでは`let`や`const`を使って変数を宣言します。変数にはさまざまなデータ型の値を代入することができます。

```javascript
// 文字列型の変数
let name = 'Alice';
console.log(name);   // Alice

// 数値型の変数（再代入不可）
const age = 25;
console.log(age);    // 25
```

### 使い分け
|  | 　const　 | 　　let　　 |　　var　　 |
|----------|----------|----------|----------|
|  再代入  |  ✕  |  ○  |○ |
|  再宣言  |  ✕  |  ✕  |○ |
|  ブロックスコープ  |  ○  |  ○  |✕ |
|  関数スコープ  |  ○  |  ○  |○ |

- `const`：`const`キーワードで宣言された変数は再代入が不可で、一度値が割り当てられると変更することができません。また、`const`はブロックスコープを持ちます。つまり、ブロック（`{}`）内でのみ有効であり、ブロックを抜けると変数は破棄されます。

- `let`：`let`キーワードで宣言された変数は再代入が可能です。また、`let`もブロックスコープを持ちます。ブロック内で宣言された`let`変数はそのブロック内でのみ有効です。

- `var`：`var`キーワードで宣言された変数は再代入が可能で、関数スコープを持ちます。関数内で宣言された`var`変数はその関数内でのみ有効です。また、`var`変数はブロックスコープではなく、関数全体でのスコープを持ちます。

### 勘違いの多いこと
`const`で宣言された変数は、再代入ができない定数となりますが、その値自体は不変ではありません。
配列の場合は、要素の変更
オブジェクトの場合は、プロパティの変更が可能です。

具体的な例を見てみましょう。

・オブジェクト
```javascript
const person = {
  name: 'John',
  age: 30
};

console.log(person); // { name: 'John', age: 30 }

person.age = 35;
console.log(person); // { name: 'John', age: 35 }
```

上記のコードでは、`const`キーワードを使用して`person`変数を定義し、オブジェクトを代入しています。
その後、`person`変数を介してオブジェクトのプロパティ`age`を変更しています。
`const`で宣言された変数`person`の値はオブジェクトへの参照であり、その参照自体は変更不可能ですが、オブジェクト自体のプロパティは変更可能です。

・配列
```javascript
const numbers = [1, 2, 3, 4];
console.log(numbers); // [1, 2, 3, 4]

numbers[2] = 10;
console.log(numbers); // [1, 2, 10, 4]

numbers.push(5);
console.log(numbers); // [1, 2, 10, 4, 5]
```
上記のコードでは、`numbers`という名前の配列を定義しています。
配列の要素は1から4までの数字です。
最初の`console.log(numbers)`では、配列の初期状態が表示されます。
結果は`[1, 2, 3, 4]`となります。
次に、`numbers`配列の3番目の要素を変更しています。`numbers[2] = 10`の行では、配列の3番目の要素が`3`から`10に変更されます。
最後に、`numbers`配列に新しい要素`5`を追加しています。
`numbers.push(5)`の行では、`numbers`配列の末尾に新しい要素`5`が追加されます。

したがって、`const`で宣言された配列の場合、配列自体の再代入はできませんが、配列の要素を変更したり、新しい要素を追加したりすることができます。

## 3. データ型 <a name="データ型"></a>
JavaScriptには以下のような主要なデータ型があります。

- 文字列 (String)
- 数値 (Number)
- 真偽値 (Boolean)
- 配列 (Array)
- オブジェクト (Object)
- null
- undefined

以下にそれぞれのデータ型の使い方と特徴について解説します。

### 文字列 (String)
文字列は、テキストを表すデータ型です。シングルクォート (`'`) やダブルクォート (`"`) で囲まれた文字列を表現します。

```javascript
let message = 'Hello';
console.log(message);   // Hello
```

### 数値 (Number)
数値は、数値データを表すデータ型です。整数や浮動小数点数を表現することができます。

```javascript
let number = 10;
console.log(number);    // 10
```

### 真偽値 (Boolean)
真偽値は、`true` (真) または `false` (偽) の2つの値を持つデータ型です。
条件の評価や制御フローの制御に使用されます。

```javascript
let isTrue = true;
console.log(isTrue);    // true
```

### 配列 (Array)
配列は、複数の値を順序付けて格納するためのデータ型です。
角括弧 (`[]`) 内にカンマ区切りで要素を定義します。

```javascript
let fruits = ['apple', 'banana', 'orange'];
console.log(fruits);    // ['apple', 'banana', 'orange']
```

配列の要素は、インデックスを使用してアクセスできます。
インデックスは0から始まり、順に増えていきます。

```javascript
console.log(fruits[0]);   // apple
console.log(fruits[1]);   // banana
console.log(fruits[2]);   // orange
```

### オブジェクト (Object)
オブジェクトは、関連するプロパティをグループ化するためのデータ型です。
中括弧 (`{}`) 内にキーと値のペアを定義します。

```javascript
let person = {
  name: 'Alice',
  age: 25,
};
console.log(person);    // { name: 'Alice', age: 25 }
```

オブジェクトのプロパティには、ドット (`.`) 演算子またはブラケット (`[]`) 演算子を使用してアクセスできます。

```javascript
console.log(person.name);    // Alice
console.log(person['age']);  // 25
```

### null型
nullは、存在しない値や空の値を表す特別な値です。
変数が値を持たないことを明示するために使用されます。

```javascript
let value = null;
console.log(value);     // null
```

### undefined型
undefinedは、値が代入されていないことを表す特別な値です。
変数が初期化されていない場合や、関数で明

示的に値を返さなかった場合などに使用されます。

```javascript
let undefinedValue;
console.log(undefinedValue);   // undefined
```

## 4. 条件分岐 <a name="条件分岐"></a>
条件文を使うと、ある条件に基づいてプログラムの分岐を行うことができます。
JavaScriptではif文、else if文、else文、switch文を使って条件分岐を表現します。
また、上記の条件文以外でも条件分岐を行うことができます。

### if
`if`文は、指定した条件が真である場合にブロック内の処理を実行します。

```javascript
let age = 18;

if (age >= 20) {
  console.log('成人です');
}
```

### else if
`else if`文は、`if`文の条件が偽であり、かつ指定した条件が真である場合にブロック内の処理を実行します。

```javascript
let age = 18;

if (age >= 20) {
  console.log('成人です');
} else if (age >= 10) {
  console.log('10代です');
}
```

### else
`else`文は、すべての条件が偽である場合に実行されるブロック内の処理を指定します。

```javascript
let age = 18;

if (age >= 20) {
  console.log('成人です');
} else if (age >= 10) {
  console.log('10代です');
} else {
  console.log('子供です');
}
```

### switch
switch文は、指定した式の値によって分岐を行います。
各ケース（case）の条件に一致する場合に、対応するブロック内の処理が実行されます。

```javascript
let day = '月';

switch (day) {
  case '月':
    console.log('月曜日です');
    break;
  case '火':
    console.log('火曜日です');
    break;
  case '水':
    console.log('水曜日です');
    break;
  case '木':
    console.log('木曜日です');
    break;
  case '金':
    console.log('金曜日です');
    break;
  default:
    console.log('週末です');
    break;
}
```

`switch`文では、`case`の後に条件を指定し、一致する場合に実行される処理を書きます。
`break`文を使って、各ケースの処理が実行された後に`switch`文を終了させることが重要です。
また、`default`キーワードを使って、どの`case`にも一致しない場合の処理を指定することもできます。

### 三項演算子
三項演算子は、簡単な条件分岐を1行で表現するための演算子です。
条件式が真の場合と偽の場合で異なる値や式を返すことができます。

```javascript
let age = 18;
let message = (age >= 20) ? '成人です' : '未成年です';
console.log(message);
```

### Nullish Coalescing演算子
Nullish Coalescing演算子は、変数が`null`または`undefined`である場合に、デフォルトの値を代入するための演算子です。

```javascript
let userName = null;
let defaultName = 'Guest';

let displayName = userName ?? defaultName;
console.log(displayName);
```

### ガード節
ガード節は、関数内で条件に基づいて処理を中断するための制御構造です。
`if`文を使用して特定の条件が満たされない場合に、処理を早期に終了させることができます。

```javascript
function greet(name) {
  if (!name) {
    console.log('名前が指定されていません');
    return;
  }

  console.log(`Hello, ${name}!`);
}

greet('Alice');
```

以上がJavaScriptにおける条件分岐の書き方になります。
これらの制御構造を組み合わせて使うことで、より柔軟な条件分岐を実現することができます。



## 5. ループ処理 <a name="ループ処理"></a>
ループ処理を使うと、同じ処理を繰り返し実行することができます。
JavaScriptでは、以下のようなループ処理の方法があります。

### for文
`for`文は、指定された回数だけ処理を繰り返すためのループです。初期化式、継続条件式、増分式を使ってループの条件を設定します。

```javascript
for (let i = 0; i < 5; i++) {
  console.log(i);
}
```

この例では、`i`を初期化して0から始め、`i`が5未満の間、ループ内の処理が実行されます。`i++`によって`i`の値が1ずつ増えます。

### while文
`while`文は、指定された条件が真の間、処理を繰り返すためのループです。条件式が最初から偽の場合、ループ内の処理は一度も実行されません。

```javascript
let count = 0;
while (count < 5) {
  console.log(count);
  count++;
}
```

この例では、`count`が5未満の間、ループ内の処理が実行されます。`count++`によって`count`の値が1ずつ増えます。

### do-while文
`do-while`文は、最初にループ内の処理を実行し、その後に条件を判定して繰り返しを制御するループです。条件が真の場合、処理は繰り返されます。

```javascript
let num = 0;
do {
  console.log(num);
  num++;
} while (num < 5);
```

この例では、最初に`num`の値を出力し、`num`が5未満の間、ループ内の処理が実行されます。`num++`によって`num`の値が1ずつ増えます。

### for...inループ
`for...in`ループは、オブジェクトのプロパティに対して反復処理を行うためのループです。
オブジェクトの各プロパティに対して、順番に処理を実行します。

```javascript
const person = {
  name: 'Alice',
  age: 25,
  city: 'Tokyo'
};

for (let key in person) {
  console.log(key + ': ' + person[key]);
}
```

上記のコードでは、`person`オブジェクトの各プロパティに対して、`for...in`ループを使用して反復処理を行っています。
ループ内では、`key`変数に各プロパティのキーが格納され、`person[key]`を使用して各プロパティの値にアクセスしています。

### for...ofループ
`for...of`ループは、反復可能なオブジェクト（配列や文字列など）の要素に対して反復処理を行うためのループです。各要素に対して、順番に処理を実行します。

```javascript
const fruits = ['apple', 'banana', 'orange'];

for (let fruit of fruits) {
  console.log(fruit);
}
```

上記のコードでは、`fruits`配列の各要素に対して、`for...of`ループを使用して反復処理を行っています。
ループ内では、`fruit`変数に各要素の値が格納され、その値を出力しています。

### forEachメソッド
`forEach`メソッドは、配列の要素に対して順番に処理を行うためのメソッドです。
`forEach`メソッドを使用すると、コールバック関数を指定して各要素に対する処理を実行できます。

```javascript
const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number) {
  console.log(number);
});
```

上記のコードでは、`numbers`配列の各要素に対して、`forEach`メソッドを使用して反復処理を行っています。
コールバック関数内では、各要素が引数`number`として渡され、その値を出力しています。

これらのループ処理を使用することで、オブジェクトや配列などのデータ構造に対して効率的に反復処理を行うことができます。

## 6. 関数 <a name="関数"></a>
![関数のメリット](https://tagnote.net/wp-content/uploads/2022/05/220525-12-768x347.png)
※画像引用(https://tagnote.net/javascript/function/)

関数は、複数の処理をまとめて実行するためのブロックです。JavaScriptでは`function`キーワードやアロー関数を使って関数を定義します。関数の定義方法や呼び出し方について詳しく見ていきましょう。

### 関数の定義（functionキーワードを使った方法）
関数を定義するには、`function`キーワードを使用します。以下の例では、`greet`という関数を定義しています。関数は`name`というパラメータを受け取り、`console.log()`を使ってメッセージを出力しています。

```javascript
function greet(name) {
  console.log(`Hello, ${name}!`);
}
```

### 関数の呼び出し
関数を呼び出すには、関数名と引数を指定します。
以下の例では、先ほど定義した`greet`関数を呼び出しています。

```javascript
greet('Alice');   // Hello, Alice!
```

`greet`関数には引数として`'Alice'`が渡されており、関数内の処理が実行されます。

### 関数の定義（アロー関数を使った方法）
ES6以降では、アロー関数（Arrow Function）と呼ばれる新しい関数の定義方法が導入されました。
アロー関数は`=>`を使って定義し、より短くコンパクトな記述が可能です。
以下の例では、`multiply`という関数をアロー関数で定義しています。

```javascript
const multiply = (a, b) => {
  return a * b;
}
```

### 関数の呼び出し
関数を呼び出す際には、関数名と引数を指定します。
以下の例では、先ほど定義した`multiply`関数を呼び出しています。

```javascript
let result = multiply(3, 5);
console.log(result);   // 15
```

`multiply`関数には引数として`3`と`5`が渡されており、関数内の処理が実行されます。
関数は`return`文を使って結果を返すことができます。

関数は再利用性やコードの整理に役立ちますので、複数の場所で同じ処理を行う必要がある場合や、ある処理をまとめて名前を付けて呼び出す場合に関数を使用すると効果的です。

## 7. イベント処理 <a name="イベント処理"></a>
JavaScriptではイベント駆動のプログラミングを行うことができます。
ユーザーの操作や特定のイベントが発生したときに処理を実行することができます。
以下の例では、クリックイベントの処理を実行する方法を示します。

### イベントの追加
イベントを処理するためには、まず対象となる要素を取得し、`addEventListener`メソッドを使ってイベントリスナーを登録します。
以下の例では、`myButton`というIDを持つボタン要素を取得し、`click`イベントに対してイベントリスナーを登録しています。

```javascript
let button = document.getElementById('myButton');
button.addEventListener('click', () => {
  console.log('ボタンがクリックされました');
});
```

上記のコードでは、`addEventListener`メソッドを使用して、`click`イベントに対して無名のアロー関数を登録しています。ボタンがクリックされると、指定した処理が実行されます。

### 他のイベント
クリックイベント以外にも、さまざまなイベントを処理することができます。

#### マウスオーバーイベント
```javascript
let element = document.getElementById('myElement');
element.addEventListener('mouseover', () => {
  console.log('マウスが要素の上に乗りました');
});
```

#### フォームの送信イベント
```javascript
let form = document.getElementById('myForm');
form.addEventListener('submit', (event) => {
  event.preventDefault(); // フォームのデフォルトの送信動作をキャンセル
  console.log('フォームが送信されました');
});
```

#### キーボードの入力イベント
```javascript
let input = document.getElementById('myInput');
input.addEventListener('input', () => {
  console.log('入力が変更されました');
});
```

## 8. 配列の操作 <a name="配列の操作"></a>
配列は複数の値をまとめて管理するためのデータ構造です。
JavaScriptでは配列の要素にアクセスしたり、要素を変更したり、追加したり、削除したりすることができます。
以下に配列の操作に関するさらなる内容を示します。

### 配列の要素にアクセス
配列の要素には、インデックスを指定してアクセスすることができます。
インデックスは0から始まる整数で、要素の位置を示します。
以下の例では、`fruits`配列の最初の要素にアクセスしています。

```javascript
console.log(fruits[0]);   // apple
```

### 配列の要素の変更
配列の要素を変更するには、インデックスを指定して新しい値を代入します。
以下の例では、`fruits`配列の2番目の要素を`grape`に変更しています。

```javascript
fruits[1] = 'grape';
console.log(fruits);   // ['apple', 'grape', 'orange']
```

### 配列に要素を追加
配列に新しい要素を追加するには、`push`メソッドを使用します。
`push`メソッドは配列の末尾に要素を追加します。
以下の例では、`fruits`配列に`melon`を追加しています。

```javascript
fruits.push('melon');
console.log(fruits);   // ['apple', 'grape', 'orange', 'melon']
```

### 配列から要素を削除
配列から要素を削除するには、`splice`メソッドを使用します。
`splice`メソッドは、指定した位置から指定した数の要素を削除します。
以下の例では、`fruits`配列から2番目の要素を削除しています。

```javascript
fruits.splice(1, 1);
console.log(fruits);   // ['apple', 'orange', 'melon']
```

### 複雑な配列

配列には上記で触れてきた一次元配列と呼ばれるもの以外にも、二次元配列、連想配列（オブジェクト）、多次元配列といった配列が存在します。


### 二次元配列
二次元配列は、配列の要素が別の配列で構成される配列です。
これにより、行と列の形式でデータを管理することができます。

以下の例は、3x3の二次元配列を作成し、要素にアクセスする方法を示しています。

```javascript
let matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

console.log(matrix[0][0]);   // 1
console.log(matrix[1][2]);   // 6
console.log(matrix[2][1]);   // 8
```

二次元配列では、各要素へのアクセスに二重のインデックスを使用します。
最初のインデックスは行を、2番目のインデックスは列を指定します。

### 連想配列（オブジェクト）
連想配列は、キーと値のペアで構成される配列です。キーを使用して値にアクセスすることができます。

以下の例は、連想配列（オブジェクト）を作成し、キーを使用して値にアクセスする方法を示しています。

```javascript
let person = {
  name: 'Alice',
  age: 25,
  city: 'Tokyo'
};

console.log(person.name);   // Alice
console.log(person.age);    // 25
console.log(person.city);   // Tokyo
```

連想配列では、キーをドット記法またはブラケット記法を使用して指定します。
キーは一意でなければならず、それに対応する値が返されます。

### 多次元配列
多次元配列は、二次元配列を拡張してさらに多くの次元を持つ配列です。
これにより、より複雑なデータの構造を表現できます。
多次元配列は必要に応じてネストされた配列として表現されます。

```javascript
let multiDimensionalArray = [
  [1, 2, 3],
  [4, [5, 6], 7],
  [8, [9, [10, 11]], 12]
];
```

二次元配列や連想配列、多次元配列を使うことで、より複雑なデータ構造を表現できます。
適切なデータ構造を選択し、プログラムの要件に応じたデータの管理を行いましょう。

## 9. DOM操作 <a name="dom操作"></a>
DOM（Document Object Model）は、HTML文書をオブジェクトとして扱うためのAPIです。
DOM操作では、HTMLの要素をJavaScriptで取得し、属性の変更、要素の作成や削除などを行うことができます。

### HTML要素の取得
HTML要素をJavaScriptで取得するには、`getElementById`や`querySelector`などのメソッドを使用します。

```javascript
// idを使用して要素を取得
let element = document.getElementById('elementId');

// セレクタを使用して要素を取得
let element = document.querySelector('.elementClass');
```

### 属性の変更
取得した要素の属性を変更するには、`setAttribute`や直接プロパティに代入するなどの方法を使用します。

```javascript
// 属性の変更
element.setAttribute('class', 'newClass');

// 直接プロパティに代入
element.className = 'newClass';
```

### 要素の作成と追加
新しい要素を作成して既存の要素に追加するには、`createElement`や`appendChild`などのメソッドを使用します。

```javascript
// 新しい要素の作成
let newElement = document.createElement('div');
newElement.textContent = '新しい要素';

// 既存の要素に追加
parentElement.appendChild(newElement);
```

### 要素の削除
要素を削除するには、`removeChild`メソッドを使用します。

```javascript
// 要素の削除
parentElement.removeChild(childElement);
```

これらの方法を組み合わせて、HTML要素を取得し、属性の変更や新しい要素の作成、要素の削除など、柔軟なDOM操作を行うことができます。

## 10. まとめ <a name="まとめ"></a>
本記事ではJavaScriptの基本的な文法と使用方法について解説しました。
JavaScriptは変数の扱い方やデータ型、条件文、ループ処理、関数、イベント処理、配列の操作、DOM操作など、さまざまな機能を持っています。
これらの知識を基礎として、より高度なJavaScriptプログラミングに挑戦してみましょう。

## 参考文献

- [入門編 - JavaScript - MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Introduction)