別に便利なtipsでも役立つ情報でもなんでもなく
ソースリーディングのメモです。
underscore.jsのソースを見ていたら
_.eachが以下のようになっていた
underscore.js
_.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
}
}
return obj;
};
この部分
obj.length === +obj.length
が恐らくレベルで何やってるかは分かるけどちょっと不思議な感じしたのでメモ
[1,2,3].length //=> 3
+[1,2,3].length //=> 3
({a:1}).length //=> undefined
+({a:1}).length //=> NaN
予想通りというかなんというか
typeof obj.length == "number" && !isNaN(obj.length)
と同等のことをしていると判断してよさそう。
処理速度面の理由なのかなーと思いつつも
実装した人にでも聞かない限り何故こうなっているのかはわからないのであった。
http://jsperf.com/is-number-and-not-nan-when-true
http://jsperf.com/is-number-and-not-nan-when-wrong-type
http://jsperf.com/is-number-and-not-nan-when-nan
numberじゃない場合こっちの方が遅いっぽいしなー
一番多そうなnullパターンを
http://jsperf.com/is-number-and-not-nan-when-wrong-type/2
さっきのforkして試してみたけど別にこの時早いというわけでもなかったのでした。