孤独プログラマー譚

孤独死が近い。

Javascript 関数のデフォルト値設定の罠

今まで何気なくやってた、関数のデフォルト値設定。

function foo(a) {
  var a = a || 1;
  ...
}

実は愚かな行動だったと知った。

JavaScriptの「&&」「||」について盛大に勘違いをしていた件 - Qiita

例えば、

foo(0); // 1

引数が 0 や false の場合、意図どおりに動作しない。

以下のようにしてやればOK。

// 1
typeof a === 'undefined' && (a = 1)
// 2
if (typeof a === 'undefined') a = 1;
// 3
a = typeof a !== 'undefined' ? a : 1;

実はJavascript、「短絡評価」をできる、数少ない過激な言語だったと知った。

論理演算子(&&, ||)の短絡評価 - Qiita

そこで、すべてのif文は、and or に書き換えられるのでは…、と危険な思想が頭をよぎった。

例えば、

if (a === 1) {
  console.log(1);
} else if (a === 2) {
  console.log(2);
} else {
  console.log('unknown');
}

個人的には、else if とか大っ嫌い。

以下のように書き換えられるか?

a === 1 && console.log(1) || a === 2 && console.log(2) || console.log('unknown')

うーん、console.log()の関数実行部分が、true を返すか、false を返すかで、挙動が変わってしまう。

いまいちだが、以下のような関数を定義した。

function t() {
  return true;
}
function f() {
  return false;
}

&& に続く関数は、絶対に true としたい。
|| に続く関数は、絶対に false としたい。

a === 1 && t(console.log(1)) || a === 2 && t(console.log(2)) || console.log('unknown')

一応、意図した動作になってるっぽい。

独自関数をグローバルに定義してるのはキモいので、何とかするとして、

この Javascript の過激な仕様に感激した。

もともとイカれた(改め、クセの強い)言語だと思っていたが、そこを遥か超えてきやがった。すげぇ。