【JavaScript】JavaScriptについて

# 記事概要
JavaScriptについて、まとめる。

# JavaScriptの役割
- ページ遷移なしで、画面の表示を切り替えられる
- 画面を更新をせずに、サーバーと通信できる

# HTMLの要素を操作する仕組み
## DOM(Document Object Model)
HTMLを解析しデータを作成する仕組み

[![Image from Gyazo](https://i.gyazo.com/151cdf7ac1daeca2737ed09ab4e7b524.png)](https://gyazo.com/151cdf7ac1daeca2737ed09ab4e7b524)

DOMツリーからHTMLを取得する方法は大きく分けて3つ。
詳細は、[こちら](https://qiita.com/likapantrip/items/89ae703c770b4e2ee6b6#documentオブジェクト)を参照

1. id名から取得する方法
1. class名から取得する方法
1. セレクタ名から取得する方法

# コードが実行される仕組み
## 概念
JavaScriptは「何かが起きたらコードを実行する」という概念に基づいて設計されている

[![Image from Gyazo](https://i.gyazo.com/919aaae54162dd692668c6309ea1a025.png)](https://gyazo.com/919aaae54162dd692668c6309ea1a025)

## イベント
HTMLに対して行われた処理の要求のこと

イベントを認識してJavaScriptのコード(特に関数)が動き出すことを「イベント発火」という

|イベント名|説明|
|-|-|
|loadイベント|ページ全体が全て読み込まれた後に、イベント発火する|
|clickイベント|指定された要素がクリックされた時に、イベントが発火する|
|mouseoverイベント|マウスカーソルが指定された要素上に乗った時に、イベントが発火する|
|mouseoutイベント|マウスカーソルが指定された要素上から外れた時に、イベントが発火する|

メソッドの詳細は、[こちら](https://qiita.com/likapantrip/items/89ae703c770b4e2ee6b6#まとめメソッド)を参照

## イベントの切り出し
[![Image from Gyazo](https://i.gyazo.com/9e9534d82d4d8e39414a7b294fe55454.png)](https://gyazo.com/9e9534d82d4d8e39414a7b294fe55454)

## インラインスタイル
HTML要素の開始タグの中に直接CSSのソースコードを記述するプロパティの指定方法

# データフォーマット
リクエストやレスポンスをはじめとしたデータのやり取りを行う際に使われるデータの型のこと

## JSON(JavaScript Object Notation)
JavaScriptをもとにして構成されたデータフォーマットのこと

動作が軽いことやモダンなフロント言語と親和性が高く管理がしやすいなどのメリットから、JSONが用いられやすい

# JavaScriptの構成
## コメントアウト
コメントアウトする方法はいくつかある。

```javascript
// コメントアウト

/* コメントアウトは
複数行に適用される */
```

## セミコロン(;)
変数定義などの最後にはセミコロンを付与し、文章の終わりであることを明示する。ただし、省略可能。

- ルール上、セミコロンを付けるケース
    ```javascript
    // （1）変数の定義
    const name = "Tom";
    
    //（2）console.logなどのメソッド（メソッドについては次の章で詳しく解説します）
    console.log(name);
    
    //（3）関数式（無名関数）
    const hello = function(){
    };
    
    //（4）関数式（即時関数）
    (function hello() {
    })();
    
    //（5）関数式（アロー関数）
    const hello = () => {
    };
    ```
- ルール上、セミコロンを付けないケース
    ```javascript
    // （1）関数宣言
    function hello(){
    }
    
    //（2）if文
    if (true) {
    } else {
    }
    ```
- セミコロンを付けないと、エラーになるケース
    ```javascript
    // (1) 即時関数を用いる場合など　※"Tom"以降の文字列もひと続きであると判断されてしまうため
    const your_name = "Tom" //セミコロンがないため、エラー発生
    
    (function sayHello(name) {
      console.log(name);
    })(your_name);
    ```

## オブジェクト
データや処理といった情報を、1つにまとめた集合体
あらかじめ用意されているオブジェクトは、[こちら](https://qiita.com/likapantrip/items/89ae703c770b4e2ee6b6#まとめオブジェクト)を参照

[![Image from Gyazo](https://i.gyazo.com/d09003b6734f33fbac9aa0813d5b3586.png)](https://gyazo.com/d09003b6734f33fbac9aa0813d5b3586)

## プロパティ
ハッシュ形式(キーとバリューの組み合わせ)で書かれる値のことであり、オブジェクトの要素(中身)を決める役割を持っている。
つまり、「オブジェクトは、プロパティの集合体から成り立っている」

[![Image from Gyazo](https://i.gyazo.com/9a619c6afe36ff17aa3d196f54ceb89b.png)](https://gyazo.com/9a619c6afe36ff17aa3d196f54ceb89b)

オブジェクトとプロパティの関係性を確認
[![Image from Gyazo](https://i.gyazo.com/5e9fb09c5b101d67fe24aa0c3c3a25fb.png)](https://gyazo.com/5e9fb09c5b101d67fe24aa0c3c3a25fb)

### プロパティの値を取得
`オブジェクト名.プロパティ名`と記述することで、オブジェクトのプロパティの値を取得できる

```javascript
// 変数humanを定義
let human = { name: 'Jhon' }

// プロパティの値を取得
console.log(human.name)
=> {name: 'Jhon'}
```

### プロパティを追加
「`オブジェクト.プロパティ`に値を代入」または、「`オブジェクト['プロパティ']`に値を代入」することで、プロパティを追加できる

```javascript
// 変数humanを定義
let human = { name: 'Jhon' }

console.log(human)
=> {name: 'Jhon'}

// プロパティを追加
human.gender = 'man'
human['age'] = 24

console.log(human)
=> {name: 'Jhon', gender: 'man', age: 24}
```

### プロパティの値を変更
`オブジェクト名.プロパティ = 変更したい値`と記述することで、プロパティの値を変更できる

```javascript
// 変数humanを定義
let human = {
  name: 'Jhon',
  gender: 'man',
  age: 24
}

console.log(human)
=> {name: 'Jhon', gender: 'man', age: 24}

// プロパティの値を変更
human.age = 25

console.log(human)
=> {name: 'Jhon', gender: 'man', age: 25}
```

### (JavaScriptにおける)メソッド
プロパティに紐づけられた処理のこと
「〇〇をしてほしい」という処理を、関数を用いることで代入できる

[![Image from Gyazo](https://i.gyazo.com/ec311429dab1a1d8a22e7e9b40a82e39.png)](https://gyazo.com/ec311429dab1a1d8a22e7e9b40a82e39)

```javascript
// 変数humanを定義
let human = {
  name: 'Jhon',
  gender: 'man',
  age: 24,

  // talkメソッドを定義
  talk: function(){
    console.log(`私の名前は${human.name}、${human.age}歳です。`)
  }
}

// talkメソッドを実行
human.talk()
=> 私の名前はJhon、24歳です。
```

## 変数
### var
再代入可能な古い書き方。基本的に使用しない
再代入・再定義ともに可能

```javascript
// 定義
var apple = "りんご"

apple
 =>'りんご'

// 再代入
apple = "りんごくん"

apple
 =>'りんごくん'

// 再定義
var apple = "りんごちゃん"

apple
 =>'りんごちゃん'
```

### const
後から書き換えることができない変数を定義する書き方
特徴として、再代入・再定義ともに不可という制約

※「後から書き換えることのできないデータ」は、正確には「定数」と呼ぶ

```javascript
// 定義
const apple = "りんご"

apple
 =>'りんご'

// 再代入
apple = "りんごくん"
 =>エラー発生

// 再定義
const apple = "りんごちゃん"
 =>エラー発生
```

### let
後で書き換えることができる変数を定義する書き方
特徴として、再代入は可能だが、再定義は不可という制約

```javascript
// 定義
let apple = "りんご"

apple
 =>'りんご'

// 再代入
let = "りんごくん"

apple
 =>'りんごくん'

// 再定義
let apple = "りんごちゃん"
 =>エラー発生
```

## 関数定義
|関数定義の種類|特徴|
|-|-|
|関数宣言|標準的な関数の定義。|
|無名関数|関数を多く使用するコードであるときに使用する。関数名の重複を避けることができる。|
|即時関数|流用する可能性のない関数を定義するときに使用する。別途関数を定義する手間がない。|
|アロー関数|無名関数または即時関数において、より省略した記述をしたい時に使用する。|

### function
`function`を使うことで、関数を定義することができる

```javascript
// 引数がある場合
function 関数名(引数) { 
  // 処理
}

// 引数がない場合
function 関数名() { 
  // 処理
}
```

```javascript
function sayHello(){
  console.log("こんにちは！")
}

sayHello()
// =>こんにちは！
```

### 関数宣言
関数を定義する

- 関数宣言を先に記述
    ```javascript
    function sayHello(){
      console.log("こんにちは！")
    }
    
    sayHello()
    
    // => こんにちは！
    ```
- 関数宣言を後で記述
    ```javascript
    sayBye()
    
    function sayBye(){
      console.log("さようなら！")
    }
    
    // => さようなら！
    // 関数宣言は先に読み込まれるので、sayBye()を実行できる
    ```

### 無名関数
関数名なしで関数を定義することができ、より簡潔なコードが記述できる

```javascript
function(引数){
  // 処理
}
```

### 関数式
無名関数を変数に代入する

```javascript
変数 = function(引数){
  // 処理
}
```

- 関数式を先に記述
    ```javascript
    const sayHello = function(){
      console.log('こんにちは！')
    }
    
    sayHello()
    
    // => こんにちは！
    ```
- 関数式を後で記述
    ```javascript
    sayBye()
    
    const sayBye = function(){
      console.log("さようなら！")
    }
    
    // エラー発生
    // sayBye()を実行した時点で、関数が定義されていないためエラー発生
    ```

### 即時関数
関数を定義すると同時に実行される構文であり、関数を定義してから呼び出すという手間を省ける

```javascript
(function 関数名(仮引数) {
  // 処理
})(実引数)
```

```javascript
// 即時関数
(function countNum(num) {
  console.log(num)
})(1)
// => 1 ※関数の呼び出し不要
```

### アロー関数
`function`の記述を省略し、その代わりに`() =>`という記述によって関数を定義する構文

```javascript
const 変数名 = (引数) => {
  // 処理
}
```

```javascript
const countNum = (num) => {
  console.log(num)
}
countNum(1)

// => 1
```

### 戻り値
関数の戻り値を`return`で明示する必要がある

```javascript
function calc(num1,num2){
  return num1*num2 // "return"を記述しているため、戻り値となる
}

const num1 = 3
const num2 = 4
console.log(calc(num1,num2))
// => 12 戻り値として12が表示される
```

## 文字列の中に変数を含める
### テンプレートリテラルを使用する
バッククォート(｀)で囲むと、文字列内に変数を挿入できる
テンプレートリテラルを使うことで、下記が可能になる
- 文字列の中に変数を埋め込むことができる
- 改行を入れることができる
- HTMLの要素を作成することができる

```javascript
const name = "Tom"
const age = 25

const introduction = `私の名前は${name}、${age}歳です`
console.log(introduction)
// => 私の名前はTom、25歳です と出力される
```

### テンプレートリテラルを使用しない
`+`を使用し、それぞれの値を連結させる

```javascript
const name = "Tom"
const age = 25

const introduction = "私の名前は" + name + "、" + age + "歳です"
console.log(introduction)
// => 私の名前はTom、25歳です と出力される
```

## 条件分岐(if文)
if文の基本的な文法は下記。

```javascript
if (条件式1) {
  // 条件式1がtrueのときの処理
} else if (条件式2) {
  // 条件式1がfalseで条件式2がtrueのときの処理
} else {
  // 条件式1も条件式2もfalseのときの処理
}
```

```javascript
const num = 60

if (num % 15 == 0) {
  console.log(`${num}は3と5の倍数です`)
} else if (num % 3 == 0) {
  console.log(`${num}は3の倍数です`)
} else if (num % 5 == 0) {
  console.log(`${num}は5の倍数です`)
} else {
  console.log(`${num}は3の倍数でも、5の倍数でもありません`)
}
// =>60は3と5の倍数です
```

## 配列
配列の記述方法は下記。

```javascript
const fruits = ["apple", "banana", "orange"]

console.log(fruits[1])
// =>banana
```

## 繰り返し処理(for文)
for文で使用する式は下記。

- 初期化式
    for文の中で使用する変数を定義。ここで定義した変数は「今何回目の処理か」を判定するために参照される
- 条件式
    for文の処理を何回繰り返すかを指定。この条件式の戻り値が`true`である限り処理は行われ続ける
- 加算式
  初期化式として定義した変数の増減を記述

```javascript
for ([初期化式]; [条件式]; [加算式]) {
  // 繰り返す処理の内容
}
```

```javascript
for ( let i = 1; i <= 100; i++ ) {
  // 100回処理を繰り返す
}
```

# JavaScriptの周辺知識
## 通信技術
### Ajax(Asynchronous JavaScript + XML)
ブラウザ上で非同期通信を利用し、ページの内容を更新する通信技術のこと

ページ内の必要な部分だけを書き換えることができ、更新する必要のない部分を無駄に読み込み直す時間がないため、ユーザーは快適にブラウザを操作することができる

## JavaScriptのライブラリ
### jQuery
DOM操作(HTMLの取得や追加削除など)を短く簡単に書くことができる
やや下火傾向だが、手軽に扱えることから未だに根強い人気がある

[公式サイト](https://jquery.com)

### Node.js
サーバサイドで動くJavaScript
処理速度が非常に速く、大量のデータ処理が可能。そのため、リアルタイムで反応が必要なチャットアプリケーションの開発によく用いられている

[公式サイト](https://nodejs.org/ja/)

### TypeScript
主な特徴としては、JavaScriptで型定義ができるということ
型を定義できる言語を静的型付け言語という

[公式サイト](https://www.typescriptlang.org/)

## コンポーネント指向を用いたライブラリ
### コンポーネント指向
機能ごとに部品として分割し、必要に応じて組み合わせて使うという考え方

## 仮想DOM
DOMとはツリー構造であり、これを読み取って再現したものが仮想DOM

### React
Facebookが開発をしたライブラリ
仮想DOMの概念によって、より早い高速なアプリケーション実装が実現できる

[公式サイト](https://ja.react.dev/blog/2023/03/16/introducing-react-dev)

### Vue.js
Reactと同様に仮想DOMの概念があり、冗長な記述を減らして、HTMLやCSSを中心にしたWebアプリ開発が可能

[公式サイト](https://jp.vuejs.org/index.html)

### Angular
Google等が開発したライブラリ
Angular自体もライブラリだが、Angular内にも標準で多数のライブラリが用意されている。したがって、外部の機能を使わずに、公式の機能のみで十分な開発を行うことができる

Angularは推奨言語にJavaScriptではなく、TypeScriptを採用していることも特徴

[公式サイト](https://angular.io/)

# 参考記事
- [【JavaScript】メソッド・オブジェクト・関数について](https://qiita.com/likapantrip/items/89ae703c770b4e2ee6b6)