当方JavaScript歴３週間目です。長らくPythonを扱ってきたので変数のスコープはグローバルか否かの２種類しか存在しなかったのですが、先日JavaScriptには`var`を付けるか付けないか以外にも`let`や`const`といったスコープが存在することを認知いたしました。

両者の違いは理解したのですが、いざ自分の書いたソースコードを`let`と`const`のみで書き直してみるとなると、どうしても`var`が良いというところが出てきてしまいます。

```

    function hoge( hoge1, hoge2 ) {
    
        if ( hoge1 === "abc" ) {
            var hoge3 = "def";
        } else if ( hoge1 === "def" ) {
            var hoge3 = "ghi";
        }
    
        return hoge1 + hoge2 + hoge3;
    
    }
    
```

上記のソースコードで言うと、「`hoge1` の値によって `hoge3` の値を変更したいけど、`hoge3`
はブロック外でも扱いたい！」といった感じです。（ただし本来はもっと長い処理を含むので、`if`毎に`return`するとソースコードが長くなってしまいます)

インターネット上の情報を見る限り、安全性が高いとかなんとかで「varは必要無い」といった意見が多く見られるのですが、このように関数内で共通の変数を宣言したい場合は、今でも`var`を使って良いのでしょうか...?

あるいはもっと良い方法があればご教授いただけるとありがたいです！よろしくお願いします。
CC BY-SA 3.0
2017-05-26T19:57:49.950
35051
2017-08-17T16:25:40.610
23391
question
javascript
JavaScript varを使わずにconst/letを使えと言われるが
`let` のスコープは、サブブロックの中でも有効ですので、  
`if` のサブブロックの外で宣言をすれば実現できます。

```

    function hoge( hoge1, hoge2 ) {
        let hoge3 = "aaa";
        if ( hoge1 === "abc" ) {
            // 2行目で宣言したhoge3
            hoge3 = "def";
        } else if ( hoge1 === "def" ) {
            // 2行目で宣言したhoge3
            hoge3 = "ghi";
        } else {
            // サブブロック内で同名の変数を宣言した場合は別の変数となる
            // 2行目のhoge3には影響しない
            let hoge3 = "jkl";
        }
    
        return hoge1 + hoge2 + hoge3;
    }
    
    hoge("abc", "xyz"); // = "abcxyzdef"
    hoge("def", "xyz"); // = "defxyzghi"
    hoge("ghi", "xyz"); // = "ghixyzaaa"
    
```
CC BY-SA 3.0
2017-05-26T21:38:29.587
35053
2017-05-26T21:38:29.587
8010
35051
answer
if ... else の部分が「条件に応じた値を1つ計算する」という目的なら、関数化するのがいいと思います

```

    function hoge( hoge1, hoge2 ) {
    
        const hoge3 = (function calcHoge3(hoge1) {
            if ( hoge1 === "abc" ) {
                return "def";
            } else if ( hoge1 === "def" ) {
                return "ghi";
            }
        })(hoge1);
    
        return hoge1 + hoge2 + hoge3;
    
    }
    
```

  * いいところ

    * スコープが小さい

      * 引数だけに依存するようにしておくと、コピペしても動くので便利
      * ロジックが肥大化してきたら、素早く関数を分離できる
      * 依存する変数が多いなら、この方法はダメ
    * 値を計算することだけが目的であることを明確にできる

      * 外側のスコープの変数(hoge1, hoge2)を変更するなら、この方法はダメ
    * ヘンな挙動をしがちな var を使ってないので、ヘンな挙動が起きないことが分かって安心

  * 悪いところ

    * インデントが深くなる
    * ごちゃごちゃしていて読みにくい

Ruby や Scala のように、if式があるなら簡単に書けるんですけどね
CC BY-SA 3.0
2017-05-29T07:26:16.367
35108
2017-05-29T07:26:16.367
9796
35051
answer
こんなのはどうです？？

```

    export const hoge = (hoge1, hoge2) => {
      let hoge3 = ''
      if (hoge1 === 'aiueo') hoge3 = 'kakikukeko'
      else if (hoge1 === 'oeuia') hoge3 = 'aiueo'
      return hoge1 + hoge2 + hoge3
    }
    
    // or
    export default {
      hoge (hoge1, hoge2) {
        // same process...
      }
    }
    
```
CC BY-SA 3.0
2017-08-17T16:25:40.610
37295
2017-08-17T16:25:40.610
24925
35051
answer