BETA

JavaScriptのMath.max/Math.minが可愛い挙動をしてくるので気をつける

投稿日:2019-05-04
最終更新:2019-05-04
※この記事は外部サイト(https://terrier.dev/blog/2019/201905032359...)からのクロス投稿です

Math.min / Math.maxを使っていたら思ったよりハマりそうな挙動があったのでまとめておきたい。
今回書いてる事はMDNにも記載されている。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max

Math.min / Math.maxは数値に変換出来ないものが一つでもあるとNaNを返す

まず、これらの関数は受け取る引数の中にNaNが混じっている場合NaNを返す。

Math.min(1, 2, 3, NaN)  
// => NaN  

そして、受け取る引数はすべてNumberにキャストされる。

Math.min(10, undefined)  
// => NaN  
Math.min(10, "foo")  
// => NaN  

Numberでキャストされて数値になるようなものはそれによって扱われる

Math.min(10, null)  
// => 0 ( NUmber(null)が0として評価される)  
Math.min(10, true)  
// => 1 ( Number(true)が1として評価される)  

数値に変換された時にどうなるかは結構覚えゲーな所があるので、そもそもこのような値が入らないようにするのが望ましいだろう。

Math.min / Math.maxは空の引数の場合Infinityを返す

ざっくり書くとこんな感じだ

Math.min()  
// => Infinity  
Math.max()  
// => -Infinity  

minやmaxのような関数に何も入れなかった場合の挙動は各言語で変わるだろうが、JavaScriptはこうなるらしい。

どういう時に気をつけるのか?

「いやいや、普通そんな書き方しないでしょう」というのもあると思うので、そもそも自分がこの挙動を知るに至った経緯を書いてみる。

確かに普通に起きないが、例えばこんな具合にfilterと組み合わせて書きたい場合、ちょっと気をつけたほうが良い

const items = [item1, item2]  
  .map(Number) // ここでNaNが混じりうる  

Math.min(...items)  
// => NaNになりうる  
const items = [item1, item2]  
  .filter(item => item > 0) // ここでitemsが空配列になりうる  

Math.min(...items)  
// => Infinityになりうる  

ちなみに、上記コードでMath.min(...items)のように配列をspreadして渡しているがこれは普通に便利。
昔はMath.min.apply(null, items)のような形で利用していたものを非常に簡素に書けている。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@terrierの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!