JavaScript

意地でもconstを使う方法

More than 1 year has passed since last update.

JavaScriptでconstを意地でも使いたい方へ。
try-catch等でもconstを使って代入を行う方法です。

前提条件

ES2015(のconst)が使用できる環境。
なお、IE11でもconstは使用できるみたいです!わーい!
ただしArrow functionsは使用できないので、function文を使用してください。ひどいよー……。

まえがき

constはES2015で追加された構文で、JavaScriptに定数という概念をもたらしました。
再代入を禁止したいので、できるだけconstを使いたいですよね。

しかし、問題となるのがtry-catch等での代入処理。
const letではブロックスコープとなるため、try文の中で変数宣言をすると、ブロックの外では変数の参照ができません。

そういった場面でもconstを使いたいと人向けの内容です。

ビフォーアフター

Before
let fileContent;
try {
    fileContent = fs.readFileSync("/path/to/file");
} catch (e) {
    fileContent = "default value";
}
After
const fileContent = (() => {
    try {
        return fs.readFileSync("/path/to/file");
    } catch (e) {
        return "default value";
    }
})();

解説

try-catchを即時関数で包んであげているだけです。
記述の仕方によっては上記のように行数が増えますが、constを使えるメリットと比べると些細なものですね。

その他

switch-case

returnを使用するため、breakを書く必要がなくなります。
そのため、Scalaのパターンマッチライクな記述になり、かなり見通しが良くなります。

before
let num = 0;
switch (flag) {
    case "A":
        num = 1;
        break;
    case "B":
        num = 2;
        break;
    case "C":
        num = 3;
        break;
}
after
const num = (() => {
    switch (flag) {
        case "A": return 1;
        case "B": return 2;
        case "C": return 3;
        default : return 0;
    }
})();

if

三項演算子よりも見やすくなる……わけないですね。
今回の技を使わず、三項演算子を使ってください。
フレンズによって得意なこと違うから!

bad
const bool = (() => {
    if (str === "str") {
        return "true";
    } else {
        return "false";
    }
})();
good
const bool = (str === "str")
        ? "true"
        : "false";

IE11

前述の通り、IE11ではArrow functionsが使えないため、IE向けにトランスパイルするか、function式を使用してください。

IE11
const element = (function () {
    try {
        return document.getElementById("id");
    } catch (e) {
        return document.body;
    }
})();

あとがき

軽くググっても出てこなかったので今回書いてみました。
これを使えば、ほとんどconstでかけると思います。
もっといい方法などありましたら教えていただけると幸いです!

参考