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、「短絡評価」をできる、数少ない過激な言語だったと知った。
そこで、すべての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 の過激な仕様に感激した。
もともとイカれた(改め、クセの強い)言語だと思っていたが、そこを遥か超えてきやがった。すげぇ。