結論
関数の引数がデフォルト値を持つ場合、 undefined を渡すことはできないので、そういう設計をやめよう
サンプルコード
以下は Node.js 6 と Chrome 59 で確認した。
デフォルト引数がない場合
> function bar(abc) { console.log(abc) }
> bar(undefined)
undefined
デフォルト引数がある場合
> function foo(abc = null) { console.log(abc) }
> foo()
null
> foo(1)
1
> foo(undefined)
null
なんでこれに気づいたか
こんなコードを書いた。
bar(foo() || undefined)
function bar(name = null) {}
この場合、foo() の戻り値が false 相当の場合、bar() の中の name が undefined になることを期待していたが、実際にはそうはならなかった。
foo() || undefined
だけを評価した場合は foo() の戻り値が false 相当の際に期待通り undefined となる。
したがって、関数に渡ってくる部分での評価で undefined を受け取らないことになっているようだ。
ちなみに Babel で変換すると
var arg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : <default>;
になるので、あーそりゃ undefined 渡せませんよね、というのは分かります。
まとめ
- 本来 JavaScript の関数の引数に undefined を渡すことはできる
- ただし Node.js や ES2015 対応していてデフォルト引数を使える場合は渡せないような挙動になる
- そもそも undefined を渡すとはナニゴトだという設計の方が正しそうなので、そうしよう
なんか今日は朝から出先を含めて高難度のリモートサポセンを断続的にやってたんだけど、PC を使わずに通話しながら調べものしたいという自分の要求に困っていた。
結論から言うと
- WiMAX + WiFiテザリング + iPod touch ( 最近また持ち歩いている )
であれば CDMA 回線使ってないので通話と両立できることが実験できた。ただし電池バカ食いなのでほんとに緊急用の方法だと思う。ここら辺だとまともに使える場所も限られるしね。
ただこの実験しようにも通話中に WiMAX on にしようとしたらいきなり Evo がリセット掛かったり、復帰したと思ってもやっぱり on にならず、通常手順で再起動したらようやく on にできるなど、
その場でサクッとセットアップできるもんじゃないのかもしんない。
サポセンの内容? IEリセットして最初の画面を通過させただけなんだけど、えらく大変だったよ! 検索プロバイダを勝手にプロバイダって省略して伝えるとこっちは何しようとしているのか分からなくなるよ!
※ そういやこの過程で iPod touch で Evernote でオフラインノート使いたかったらプレミアム会員になってねって言われた。昔は Star して保存できてたのに、残念だな。
先日注文したメガネが仕上がったはず1なので受け取りに行ってきた。
で、予備のメガネは J!NS PC カスタムなので
予想通り本物のブルーライトカットレンズについて語られた。
うん、知ってた。そういう店だって。知ってて安いから J!NS 買ってるんだ。いいものがいいものだってことくらい分かるよ。
まぁ収穫はあった。
レンズの色でなくコーティングでカットするレンズはむしろ青い
とは言え、ちなみにおいくらとは聞く気にならなかった。うん、そういうこと。
連絡なかった。 ↩
うちの機械と回線の遅さを再認識したというかなんと言うか。
うちで Fastladder を試したら Bloglines って遅いなーと思うようになってきた。しかし移行しようにも keep new の記事がやたら多く、これをなくしてしまわないことには。とりあえずドカドカと open してささっと読んで要りそう1なら del.icio.us に突っ込んでいく、という作業をくり返している。つらい。
Camino だから遅いのかしらんと思って Safari にしてみたけどさすが Safari 1.3、JavaScript 周りの処理は速くはない。
今週は本を読もうと思っていたんだけど、なんかいつも以上に画面にへばりつくことになってしまった。肩と腰とヒザがつらい。
基準は、何かの拍子に検索したときに引っかかってくれると嬉しいかもしれないと思うかどうか ↩
具体的には改行を含むテキストを1行1要素の配列にぶった切ろうと思って以下の処理を行った。
var arr = str.split( /(?:\r\n|[\r\n])/ );
すると以下のように IE というか JScript エンジンだけ(つまり WSH でも同じ)できあがった配列から空の要素が消え、空行がなかったことになってしまう。
エンジン | 空要素 |
JScript 5.6 | 消える |
Firefox 1.5.4 | 消えない |
Safari 1.3 | 消えない |
Opera 8.5 | 消えない |
これは正規表現をシンプルにしても同じ。
var arr = str.split( /\n/ );
ただし、文字列で split すると JScript でも空要素は消えない。
var arr = str.split( "\n" );
それなんて「仕様」?
document.write() の連発がださいけど下のスクリプトをコピペして開いてもらうと確認できる。IE では 6 と表示されるが、IE 以外では 7 と表示される1。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>Test of split with RegExp</title>
</head>
<body>
<h1>Test of split with RegExp</h1>
<script type="text/javascript"><!--
document.open();
var str = "wedjweo\nweoidjwe\nweiodjw\n\nweid\nwoeid\nweoij";
var arr = str.split( /(?:\r\n|[\r\n])/ );
document.write( '<pre>' );
document.writeln( '<h2>original text</h2>' );
document.writeln( str );
document.writeln( '<h2>number of array items</h2>' );
document.writeln( arr.length );
document.writeln( '<h2>splitted array</h2>' );
document.writeln( arr );
document.writeln( '<h2>rebuilded text</h2>' );
document.write( arr.join( "\n" ) );
document.writeln( '</pre>' );
document.close();
// -->
</script>
<p>
If you use split with RegExp,
JScript engine automatically remove array's empty item :-(
</p>
</body>
</html>
MacIE 5 では正規表現の (?: の書き方に対応してないのでどのみち動きません。 ↩