---
# System prepended metadata

title: 'JavaScript 再入門 #1'
tags: [JavaScript]

---

# JavaScript 再入門 #1
###### tags: `JavaScript`
年末年始体調不良で死んでたので本日開始。
- 参考: [【JS】初級者から中級者になるためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
## スコープ
- グローバルスコープ
    - `const` や `let` で定義・代入した値はスクリプトスコープに位置する
- スクリプトスコープ
    - `var` や `function` で定義・代入された値は `window` オブジェクトのプロパティとして格納され、グローバルスコープに位置する
- 関数スコープ
    - `function` で関数宣言されたあとの `{}` の内部の範囲のこと。一般的に関数の外部からは値の取得はできない
- ブロックスコープ
    - `{}` の内部の範囲のこと。明示的にブロックスコープとして利用する場合には変数の宣言には `let` か `const` しか利用できない。
    - ブロック内の `function` はブロック外からも呼び出しができるが、`const` などの変数宣言に無名関数を代入する形で記述するとブロックスコープが適用されエラーとなる
## レキシカルスコープ
- コードを書く場所によって参照できる変数が変わるスコープで、静的スコープとも呼ぶ
![](https://i.imgur.com/4JeUZbW.png)
## スコープチェーン
- 上記の図のようにスコープが別のスコープを範囲内に含んでいる状態のこと
- 変数名を取得しに行く場合、より深い階層にあるスコープからグローバルスコープに向かって変数を探しに行くようになっている
## クロージャー
- レキシカルスコープの変数を関数が使用している状態のこと
![](https://i.imgur.com/pn1Eam6.png)
- より深い階層の関数からその上の関数が保持する変数にアクセスするような状態
- クロージャーの利用
    - プライベート変数の定義
        - 外部から参照はできず関数内に一意の値を保持できる
        - 1,2,3...とカウントする関数を作る場合
        ![](https://i.imgur.com/zzQ3pgT.png)
    - 動的な関数の生成
        - 複数の引数を可変させ実行結果が変化する関数を作る場合
        ![](https://i.imgur.com/W6Q871U.png)
## 即時関数
- 定義と同時に一度だけ実行される関数のこと
## 演習
- クロージャー
メソッドの直接定義どんなだっけ？ってなってつまずいた
```javascript
function calcFactory(val) {
  return {
    plus: function (target) {
      const newVal = val + target;
      console.log(`${val} + ${target} = ${newVal}`);
      val = newVal;
    },
    minus: function (target) {
      const newVal = val - target;
      console.log(`${val} - ${target} = ${newVal}`);
      val = newVal;
    },
    multiply: function (target) {
      const newVal = val * target;
      console.log(`${val} x ${target} = ${newVal}`);
      val = newVal;
    },
    divide: function (target) {
      const newVal = val / target;
      console.log(`${val} / ${target} = ${newVal}`);
      val = newVal;
    },
  };
}

const calc = calcFactory(10);
calc.plus(5);
calc.minus(3);
calc.multiply(3);
calc.divide(2);
```