web-dev-qa-db-ja.com

( "foo" === new String( "foo"))がJavaScriptでfalseと評価されるのはなぜですか?

文字列値を比較するときは常に===(3つの等しい、厳密な比較)を使い始めましたが、今では

"foo" === new String("foo")

これは偽であり、これと同じです:

var f = "foo", g = new String("foo");
f === g; // false

もちろん:

f == g; // true

では、文字列の比較には常に==を使用するか、比較する前に変数を常に文字列に変換することをお勧めしますか?

98
Michael Butler

_"foo"_は文字列primitiveです。 (この概念はC#またはJavaには存在しません)

new String("foo")はボックス化された文字列オブジェクトです。

_===_演算子 プリミティブとオブジェクトでは動作が異なります
(同じタイプの)プリミティブを比較する場合、_===_は、両方が同じ値を持つ場合にtrueを返します。

オブジェクトを比較する場合、_===_は、それらが同じオブジェクトを参照している場合にのみtrueを返します(参照により比較)。したがって、new String("a") !== new String("a")となります。

あなたの場合、オペランドが異なる型であるため、_===_はfalseを返します(1つはプリミティブで、もう1つはオブジェクトです)。


プリミティブはオブジェクトではありません。
typeof演算子は、プリミティブに対して_"object"_を返しません。

(それをオブジェクトとして使用して)プリミティブのプロパティにアクセスしようとすると、JavaScript言語はそれをオブジェクトにボックス化し、毎回新しいオブジェクトを作成します。これは 指定 で説明されています。

これが、プリミティブにプロパティを配置できない理由です。

_var x = "a";
x.property = 2;
alert(x.property) //undefined
_

_x.property_を書き込むたびに、differentボックス化Stringオブジェクトが作成されます。

126
SLaks

===を使用して、

  • オブジェクトは、それ自体への別の参照を除いて、決して等しいことはありません。

  • タイプと値が同じである場合、プリミティブは別のプリミティブと比較すると等しいです。

34
user1106925

newという言葉はここでは犯罪者です(いつものように、言ってもいいでしょう)...

newを使用するときは、objectを使用したいという希望を明示的に表します。それはあなたにとって驚くべきことかもしれませんが、これは:

var x = new String('foo');
var y = new String('foo');
x === y; 

...強力なfalseを提供します。それは簡単です。比較されるのはオブジェクトの内部ではなく、オブジェクトの参照です。そしてもちろん、それらは等しくありません。2つの異なるオブジェクトが作成されたからです。

おそらく使用したいのはconversion

var x = String('foo');
var y = String('foo');
x === y;

...そして、期待どおりに結果としてtrueが得られるので、あなたは喜び、等しいfoosで永遠に繁栄することができます。 )

10
raina77ow

fooは純粋な文字列で、new String("foo")はオブジェクト文字列です

4
Danilo Valente

Node.jsからREPL(インストールされている場合、コマンドラインの「node」):

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'
2
mda