1

私はこのコードを持っています:

function getSessionGUID() {
   return (S4()+S4());
}

function S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}

明らかに文字列を返しますが、何度も実行すると、無限大を返すことがあることに気付くでしょう。

for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
871 x INFINITY

次に、| 0を削除すると、問題が解決することに気付きました。

function S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}

結果:

for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
undefined

なぜこれが起こるのですか?どちらの場合も、値は文字列に変更されます。

4

5 に答える 5

3

16進文字列を生成しています。

演算子を使用する==と、インタープリターは2つの値を同じデータ型に強制変換しようとします。文字列をと比較する場合Infinity、その中間データ型はNumberです。これらの文字列に文字「e」(有効な16進数)が含まれていて、それらが強制的に変換されるとNumber、javascriptはこれを10 ^ xとして解釈し、最終的には巨大な数値になります。

Numberjavascriptのsは8バイトであるため、より大きいもの1.7976931348623157e308はすべて。と見なされInfinityます。

これを修正する最も簡単な方法は、文字列が数値に強制変換されないようにをに変更する==ことです。===

if(getSessionGUID() === Infinity)

http://jsfiddle.net/Uhkxm/

于 2012-11-14T19:14:54.720 に答える
2

JavaScriptは動的に型付けされます。整数の浮動小数点はありません。文字列データ型。その変換はすべて、コンテキストに応じて内部で行われます。

+は、コンテキストに応じて文字列の連結または加算になります。

編集:お詫び。遅すぎる。しかし、無限大と比較した場合、それは==数値への変換を実行することでした。場合によっては、有効な番号を生成しました。

于 2012-11-14T18:54:16.730 に答える
2

私はそれを理解したと思います。私のテストコードを除いて、これらすべてに実際には何も問題はありません。

この文字列「11e51354」を取得すると、Javascript が true に等しくなる可能性のあるすべての型をチェックするため、true にアサートすることができます。

"11e51354" == Infinity # True

正しいテストは次のようになります。

"11e51354" === Infinity # False

それはまだ文字列ですが、どういうわけかGETリクエストで送信しているときに、Infinityを与える数値型に変換されていました.

于 2012-11-14T19:06:12.970 に答える
2

このテストは答えを明らかにします:

for (var i = 0; i < 100000; i++){
  var x=getSessionGUID();
  if(x == Infinity) console.log(x); }
}

61e93284またはのような値を記録します1413e390

これらの値は有効な数値であり、Number 型には大きすぎるため、数値として解釈されると Infinity としてキャストされます。

==テストでに置き換えた場合===、変換は行われず、何もログに記録されません。==変換はオペレーターによって行われます。

于 2012-11-14T19:11:09.993 に答える
0

数値型が本当に必要な場合は、常に次を使用できます。
console.log(Number("1"));

于 2012-11-14T18:57:15.537 に答える