32

このステートメントを JSLint に入力しました。

var number = new Number(3);

そして、次のメッセージを受け取りました。

Number をコンストラクタとして使用しないでください。

何故ですか?このステートメントは、プリミティブ値ではなく数値オブジェクトを作成しているため、使用が問題になる理由がわかりませんnew

編集:すべての応答に感謝します。彼らは私にさらに考えさせたので、フォローアップの質問をここに投稿しました.

4

6 に答える 6

39

===を壊し、typeofが "object"を返すことに加えて、Numberコンストラクターを使用すると、ブールコンテキストでの値の使用方法も変更されます。「newNumber(0)」はリテラル値ではなくオブジェクトであるため、nullではないため「true」と評価されます。したがって、たとえば:

var n1 = 0;
var n2 = new Number(0);

n1 == n2  // true
n1 === n2 // false
if (n1) {
    // Doesn't execute
}
if (n2) {
    // Does execute, because n2 is an object that is not null
}

数値リテラルと数値オブジェクトの間で===を壊すよりもさらに悪いことに、==は2つの数値オブジェクト間でも機能しません(少なくとも直感的な方法ではありません-それらは同一性をテストし、同等性をテストしません)。

var n1 = new Number(3);
var n2 = new Number(3);

alert(n1 == n2); // false
alert(n1 === n2); // false
于 2008-12-15T19:31:35.893 に答える
19
var number = new Number(3);
alert(typeof number); // gives "object"

変数numberの型を にすることObjectは、おそらく最も望ましい結果ではありません。一方:

var number = Number(3);
alert(typeof number); // gives "number"
于 2008-12-15T18:21:57.780 に答える
6

new Number() は数値リテラルと同じオブジェクトを返しません。これは、new Number() を使用すると === が壊れることを意味します。これは、Javascript で完全に等しいかどうかをチェックする最良の方法です。

>>> 3 == 1 + 2
true
>>> 3 === 1 + 2
true
>>> new Number(3) == 1 + 2
true
>>> new Number(3) === 1 + 2
false

JSLint の動作の理論的根拠は、著者の著書JavaScript: The Good Partsの付録 C にあります。

于 2008-12-15T18:28:19.060 に答える
6

残念ながら、JSLint のドキュメントには「表示されるとは思わない」以上の詳細は記載されていないため、推測に任せます。私自身の疑いでは、これは型チェックを容易にするためであるということです:

assert(typeof 3             === "number");
assert(typeof new Number(3) === "object");

コード内で 2 つを混在させると、型チェックがより複雑になります。

if (typeof foo === "number" || foo instanceof Number) { … }

ただし、JSLint は Object コンストラクターと Array コンストラクターにも問題がありますが、これらはこの区別をしていません。

assert(typeof []           === "object");
assert(typeof new Array()  === "object");
assert(typeof {}           === "object");
assert(typeof new Object() === "object");

編集:スティーブンの答えは優れたポイントを提起します—非型キャスト等価演算子(===)。数値オブジェクトと数値プリミティブは、値が同じであっても、この演算子によって等しいとは見なされません。

assert(3 !== new Number(3));
于 2008-12-15T18:22:04.580 に答える
5

速度が遅く、より多くのメモリが必要です。ランタイムは、不変のリテラルを不変のリテラルとして扱うことができます。つまり3、コードのどこかで遭遇したときに、それを共有オブジェクトに最適化できるということです。コンストラクターを使用すると、Numberインスタンスごとに新しいメモリが割り当てられます。

于 2008-12-15T19:43:19.050 に答える