【新機能】作り忘れたまとめはありませんか?31日前まで期間指定してまとめが作れる高度な検索ができました。有料APIだからツイートの漏れはありません!

JavaScript の算術演算子と数値変換

valueOf と ToNumber とあとついでに parseInt のことについて適当に調べてそれを垂れ流したのでまとめてみた。 調べてなくてあまり確証のないところは”(たぶん”とかつけているけれど、それ以外は一応調べたつもりなのでだいたい合ってるハズ。 但しブラウザ対応までは調べていないので、悪しからず。
2434view 0コメント
4
ログインして広告を非表示にする
(っ=﹏=c) .。o○ @itchyny 2010-12-20 21:37:09
var t = +new Dateって, これなんで動くんだっけか
(っ=﹏=c) .。o○ @itchyny 2010-12-20 21:46:04
+付けたらvalueOfが返されるのか, 巧妙だ http://goo.gl/NYIem
(っ=﹏=c) .。o○ @itchyny 2010-12-20 22:07:33
どうだ, 混乱してきただろう! ハッハッハッ http://twitpic.com/3hqyck
 拡大
Tomoki UDA @t_uda 2010-12-20 22:55:17
いちにぃさんのついーとを見て String の valueOf 絡みのことを調べているが、これは思った以上にややこしい。そして思わぬ収穫が。 /[Mm]ath/
Tomoki UDA @t_uda 2010-12-20 23:13:46
. #JavaScript (valueOf について)話をしよう・・・ #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-20 23:17:34
結論から言うと、算術演算子は、内部で被演算項に対して数値変換を施してから演算を行うようになっている。従って、次のようなコードは結果が数値型になる(ことが期待される): "1" - "2"; // => -1 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-20 23:59:25
確認は Firefox, Chrome でとった。そしてこれは ECMAScript 仕様に則った挙動である。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:24:42
ここで、数値型への変換が呼ばれる前に、 valueOf が呼ばれる場合がある。(なお ECMAScript の仕様ではそれぞれ "ToNumber", "GetValue" となっている) #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:28:15
呼ばれる場合がある、というのは必ずしも valueOf は呼ばれないということである。実は valueOf と GetValue は等価ではない。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:30:41
仕様にある "GetValue" というのは、あくまで「ECMAScript のオブジェクトから primitive 値を取得する」という意味である。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:33:14
そして Object は全てのオブジェクトの継承元であるから、 ***.prototype.valueOf は、Number や String にも(nativeに)実装されている。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:35:24
従って JavaScript のオブジェクトなら全て GetValue の時に valueOf が呼ばれていることになる(そしてこの呼び出しは時に script レベルで再帰的でもあるかもしれない)。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:37:20
ここで重要なのが primitive 値だ。 primitive な string や number は普通のオブジェクトとは全く異なる。これは”GetValue が返すべき値そのもの”である(たぶん。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:38:21
数値リテラル初期化子や、文字列リテラル初期化子が生成する値は、いずれも primitive 値である。それぞれ、Number, String の instance で は な い。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:42:57
例えば +3 というコード片において、3 は primitive 値 [3] を生成するから、 [GetValue] によってその値自身 [3] を返す。ここで valueOf が呼び出される余地はない(ハズである。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:56:43
((ここら辺まで ECMAScript とか valueOf とかの実装寄りの話 / こっからついでに分かった話)) /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:59:22
JavaScript で文字列->数値に変換するときは、よく parseInt 関数が使われる。(parseInt を用いるのが最も一般的だと思われる) #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 00:59:46
(と言うか、他に知らない。ECMAScript レベルで何か規定されていれば流石に知ってるハズ。) /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:02:21
ところが、parseInt には色々と問題がある。ブラウザによって必ずしも同じ値を返さなかったりするのはまぁいつものことだが、引数の与え方によっては 8 進数表記だと解釈されたりしてしまう。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:07:05
例えば、 parseInt("010") は基数を指定していないため、多くのブラウザで 8 が返ってくる。ちなみに IE9 では 10 が返ってきた。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:08:28
ECMAScript draft 5th ed. では、第二引数省略時は必ず 10 進表記で変換することになったらしいので、IE9 の挙動が正しい。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:09:50
と言ってもそんなのは最近の出来事である。昔の draft では実装依存だったらしいので、parseInt の第二引数を指定しない場合の結果はあまり期待できない。(なので、第二引数には必ず 10 をつけろ、と言われている) #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:12:18
また、parseInt は科学表記(2×10^-5 を表す 2.0e-5 など)に対応していない。 parse 中に、期待されない文字が現れた場合以降の文字は切り捨てられる。 #JavaScript /[Mm]ath/
Tomoki UDA @t_uda 2010-12-21 01:13:15
例えば: parseInt("2e-3"); // => 2 parseInt("1abcd"); // => 1 #JavaScript /[Mm]ath/
残りを読む(10)

ブックマークしたタグ

あなたの好きなタグをブックマークしておこう!話題のまとめを見逃さなくなります。
ログインして広告を非表示にする
ログインして広告を非表示にする