Javascriptの基礎

# はじめに
javascriptについての基礎を忘備録として残す

# 変数宣言の方法
javascriptの変数宣言は、原則3種類存在する。
- **const**
値が変わらない（変数に再代入しない）変数を宣言する。

```js:例
const sample = "おはよう"

sample = "おはよう"
// 再代入NG →エラーが起こる

const sample = "おはよう"
// 再宣言NG →エラーが起こる

console.log(sample)
// => おはよう と出力される
```

- **let**
値が変わる（変数に再代入する）変数を宣言する

```js:例
let sample = "おはよう"

sample = "おはよう"
// 再代入OK

let sample = "おはよう"
// 再宣言NG →エラーが起こる
```

※出力方法は、`const`と同じ

- **var**
原則使用しない

# 文字列の中に変数を含める方法
以下のようにJavaScriptでは2つの方法があります。

- `+`を用いてそれぞれの値を連結させる
- テンプレートリテラル``` `${変数名}` ```を使用する

```js:テンプレートリテラルを使用しない場合
const name = "Tom"
const age = 25
const introduction = "私の名前は" + name + "、" + age + "歳です"
console.log(introduction)
// => 私の名前はTom、25歳です と出力される
```

```js:テンプレートリテラルを使用した場合
const name = "Tom"
const age = 25
const introduction = `私の名前は${name}、${age}歳です`
console.log(introduction)
// => 私の名前はTom、25歳です と出力される
```

# 条件分岐

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

ポイントは以下の通り
- 条件式は`()`でくくること
- 条件式の後に続く波括弧`{}`内の処理が実行されること
- 複数条件を指定する場合は、`else`のあとに続けて`if`文を記述すること

# 配列の要素を取得する
以下の通り

```js
const list = ["Ruby", "Ruby on Rails", "JavaScript", "HTML", "CSS"]

console.log(list)

console.log(list[2])
```

# 繰り返し処理
for文を使用する

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


- **初期化式**
for文の中で使用する変数を宣言します。ここで宣言した変数は「今何回目の処理か」を判定するために参照されます。
↑↑↑↑↑↑↑ 編集リクエストの内容

- **条件式**
for文の処理を何回繰り返すかを指定します。この条件式の戻り値がtrueで有る限り処理は行われ続けます。

- **加算式**
初期化式として宣言した変数の増減を記述できます。`i = i + 1`とすれば1周ごとに1が加算されて、処理が実行されます。
`i = i + 1`の省略形として以下のような選択肢があります。
`i += 1`
`i++`
慣習的に`i++`と記述されることが多い

```js:使用例
for ( let i = 1; i <= 100; i++ ) {
  // 100回処理を繰り返す
}
```

```js:使用例2
let count = 1
for (let i = 1; i <= 10; i += 1) {
  console.log(`${count}回目の出力`)
  count +=  1
}
```

# 配列の繰り返し処理
`forEach`メソッドを使用する

```js
配列.forEach( function(value){
  // 処理の記述
})
```

```js:使用例
fruits = ["apple", "orange", "grape"]
fruits.forEach( function(item) {
  console.log(item)  // 配列に格納されている要素の数だけ実行される
})
```

# 関数の宣言方法
関数とは、Rubyにおけるメソッドのようなもの。
(Rubyでは`def メソッド名`～`end`で定義する)

```js
function 関数名(引数) {
  // 処理
}
```

```js:使用例
function sayHello(){
  console.log("こんにちは！")
}

sayHello()
```

⇨コンソール上で「こんにちは」と表示される

＜注意点＞
戻り値は、`return`文で明示的に表現することが必要

```js:returnが無いと表示されない
function calc(num1,num2){
  return num1*num2
}

const num1 = 3
const num2 = 4
console.log(calc(num1,num2))
```

# 関数宣言の方法（関数宣言と関数式）

```js:関数宣言
function 関数名( 引数 ){
  // 関数内の処理
}
```

```js:関数式
const 変数 = function( 引数 ){
  // 関数内の処理
}
```

関数宣言で関数名として定義しているものを、無名の関数を変数に代入する形で表現する方法

### 関数宣言と関数式の違い
関数宣言と関数式では読み込まれるタイミングが異なる。
- **関数宣言は先に読み込まれ、関数式は書かれた順番で読み込まれる**

### 関数式の定義方法の種類

```js:関数式（無名関数）
const hello = function(){
  console.log('hello')
}
```

```js:即時関数 ()
(function countNum(num) {
  console.log(num)
})(1)  // ←numに渡される引数
```
※`(1)`で即時関数を呼び出している

```js:アロー関数
const 変数名 = () => {
  処理
}
```
関数式の`function`を省略し、`() =>`に書き換えて簡略化した書き方

# JavaScriptにおけるセミコロン；
文章の終わりを示す際に、末尾にセミコロン`;`をつける
使い方と使える場面、使わない場面は下記の通り


```js:[例]ルール上セミコロンを付ける
// (1) 変数の宣言
const name = "Tom";

//（2）console.logなどのメソッド（メソッドについては次の章で詳しく解説します）
console.log(name);

//（3）関数式（無名関数）
const hello = function(){
};

//（4）関数式（即時関数）
(function hello() {
})();

//（5）関数式（アロー関数）
const hello = () => {
};
```

```js:【例】ルール上セミコロンを付けない
//（1）関数宣言
function hello(){
}

//（2）if文
if (true) {
} else {
}
```

しかし、以下のように即時関数を用いる場合などはエラーとなることがあります。`"Tom"`以降の文字列もひと続きであると判断されてしまうためです。

```js:【例】セミコロンを付けないことでエラーとなる例
// エラーとなる
const your_name = "Tom"

(function sayHello(name) {
  console.log(name);
})(your_name);

// エラーにはならない
const your_name = "Tom";

(function sayHello(name) {
  console.log(name);
})(your_name);
```

# オブジェクトとプロパティの概念
JavaScriptにおけるオブジェクトとは、データや処理の集合体のこと
データは、ハッシュ形式で宣言する。
この際のキーとバリューをセットでプロパティと呼ぶ。

```js:イメージ図
let human = {
  name: "Jhon",
  gender: "man",
  age: 24,
}
```

`name: "Jhon"`等のキー名＋バリューをプロパティ
`{}`中身をまとめてオブジェクト

オブジェクトのバリュー（値）を取り出すには、
`human.name(オブジェクト名.プロパティ名)`で取り出すことができる。

### オブジェクトにプロパティを追加する方法
- `オブジェクト.プロパティ`に値を代入する
- `オブジェクト['プロパティ']`に値を代入する

```js:書き方
let human = { name: 'yamada' }
human.age = 25
human['address'] = 'Tokyo'
```

### プロパティの値変更

```js
let human = {
  name: "yamada",
  age: 25,
  address: 'Tokyo'
}

human.name = "yabe"
```
    →yamadaからyabeに変更できる

### オブジェクト内の処理の宣言について
オブジェクト内における処理は、メソッドと呼ばれ、関数で宣言できる。
なお、処理はプロパティに紐づく。
宣言方法の書き方や、呼び出し方は下記の通り。

```js
let human = {
  name: "yamada",
  age: 25,
  address: 'Tokyo',

  talk: function(){
    console.log(`私の名前は${human.name}、${human.age}歳です。住所は${human.address}です`)
  }
}

human.talk()
```

# あらかじめ定義されているオブジェクト
- **windowオブジェクト**
windowオブジェクトとは、ブラウザの情報を持っているオブジェクトです。ブラウザの情報をもつため、ブラウザオブジェクトと呼ばれる。
JavaScriptで予め定義されているメソッドやオブジェクトは全てwindowオブジェクトのプロパティであると言える。
最上位のWindowオブジェクトを起点として、下位にその他のオブジェクトが属する構造になっています。ブラウザが起動するタイミングで自動的に生成され、JavaScriptからアクセスすることが出来ます。

```js:windowオブジェクトの使用例
window.alert("ブラウザオブジェクトの取得に成功！")
window.オブジェクトは省略できる。
```


- **documentオブジェクト**
ブラウザ上で表示された情報(HTML)を操作する事ができるオブジェクトです。
このdocumentオブジェクトは非常に多くのプロパティやメソッドを持っています。したがって、documentオブジェクトはこれからHTMLに対して何か処理をする際は頻繁に使用するオブジェクトとなります。


### HTMLを取得する方法
DOMツリーからドキュメントオブジェクトを使用して要素を取り出し、CSS等の処理に変更を加えることができる。

- **DOM（Document Object Model）**
DOMとは、HTMLを解析しデータを作成する仕組み

- **document.getElementById("id名")**
`document.getElementById("id名")`は、DOMツリーから特定のHTMLの要素を取得するためのメソッドの1つです。引数に渡したidを持つ要素を取得します。
以下のように書くことで、マッチするidを持つHTMLの要素を取得することができます。

```js:【例】特定のidを持つ要素の取得
//id名がhogeの要素を指定する場合
document.getElementById("hoge")
```

- **document.getElementsByClassName("class名")**
classを指定して取得する際はこちらを利用します。ここで気をつけたいのは、`getElements`と複数形になっていることです。
id名はhtml上に必ず1つしか存在しないため、`document.getElementById("id名")`を用いると1つの要素を取得することになります。一方、HTML上に同じclass名を持つ要素は複数存在することが考えられるため、`getElementsByClassName("class名")`の場合は同じclassを持つ要素を全て取得することになります。
以下のように書くことで、class名とマッチするデータを取得することができます。


```js:【例】特定のclass名を持つ要素の取得
//class名がfugaの要素を指定する場合
document.getElementsByClassName("fuga")
```


- **document.querySelectorAll("セレクタ名")**
セレクタ名とは、CSSでスタイルを適用するために指定している要素です。セレクタ名を指定して取得する場合、`querySelectorAll`メソッドを使用します。HTML上から、引数で指定したセレクタに合致するものをすべて取得します。
最も頻繁に使用するセレクタ名として、class名、id名、HTMLタグを覚えておきましょう。
書き方として、class名は`(".class名")`、id名は`("#id名")`、HTMLタグは`("タグ名")`と表記します。

```js:【例】指定したセレクタ名を持つ要素すべてを取得
//class名がfugaの要素を指定する場合
document.querySelectorAll(".fuga")
//id名がhogeの要素を指定する場合
document.querySelectorAll("#hoge")
//h1タグの要素を指定する場合
document.querySelectorAll("h1")
```

関連して、`querySelector`というメソッドもあります。`querySelector`を用いれば、HTML上から引数で指定したセレクタに合致する要素のうち一番最初に見つかった要素1つを取得することもできます。

```js:【例】セレクタ名を指定した要素のうち、一番最初に見つかった要素だけ取得
//id名,class名,タグ名の指定方法は、querySelectorAllメソッドと同じ
document.querySelector("セレクタ名")
```

### getElementsByClassNameとquerySelectorAllの違い
`getElementsByClassName`と`querySelectorAll`の違いは戻り値にあります。`getElementsByClassName`は`HTMLCollection`というオブジェクトを、`querySelectorAll`は`NodeList`というオブジェクトを戻り値として返します。

```html:【例】取得するHTMLの情報
<ul class="hidden" id="modal">
  <li class="modal-list">リスト1</li>
  <li class="modal-list">リスト2</li>
  <li class="modal-list">リスト3</li>
  <li class="modal-list">リスト4</li>
</ul>
```

```js:【例】HTMLCollectionとNodeListの違い
console.log(document.getElementsByClassName("modal-list"))
// => HTMLCollection(4) [li.modal-list, li.modal-list, li.modal-list, li.modal-list]

console.log(document.querySelectorAll(".modal-list"))
// => NodeList(4) [li.modal-list, li.modal-list, li.modal-list, li.modal-list]
```

**`HTMLCollection`と`NodeList`では使えるメソッドが違います**。例えば、`forEach`メソッドを使用したい場合は、`NodeList`オブジェクトを戻り値として返す`querySelectorAll`を使用します。

# 機能の実装
- イベント
JavaScriptにおけるイベントとは、HTMLに対して行われた処理の要求のことをいいます。例えば「ユーザーがブラウザ上のボタンをクリックした」「テキストフィールドでキー入力をした」「要素の上にマウスカーソルを乗せた」などがいずれもイベントです。
また、イベントを認識してJavaScriptのコード（特に関数）が動き出すことを「イベント発火」と言います。
代表的なイベント発火の例として、以下のような種類があります。

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

これからイベントを発火させる記述をします。
JavaScriptではイベントを発火させるために、`addEventListener()`というメソッドを使用します。

### addEventListener()メソッド
イベント発火の際に実行する関数を定義するためのメソッドです。
`addEventListener()`メソッドは以下のようにして実行します。

```js:【例】addEventListenerメソッド
要素.addEventListener('イベント名', 関数)
```