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


98

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

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

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

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

もちろん:

f == g; // true

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


6
たぶん、それfooは純粋な文字列でnew String("foo")あり、オブジェクト文字列だからです
Danilo Valente


6
使用するのではなく、new String(完全に無意味な)文字列を作成しないことをお勧めします==
Esailija

2
new String("foo")そもそもなぜJavascriptのような構文を使用したいのでしょうか。コード、つまりjQueryでそのようなコードを見たことがありません...
Robert Koritnik

2
String(obj)「string」パラメータを受け取ったら、を使用してボックス化された文字列をプリミティブに変換できます。("foo" === String(new String("foo"))) === true
OrangeDog

回答:


126

"foo"文字列プリミティブです。(この概念はC#またはJavaには存在しません)

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

===オペレータは、プリミティブやオブジェクト上で動作が異なります
(同じタイプの)プリミティブを比較するときに===、両方が同じ値を持っている場合はtrueを返します。

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

あなたのケースで===は、オペランドが異なるタイプ(一方はプリミティブで、もう一方はオブジェクト)であるため、falseを返します。


プリミティブはオブジェクトではありません。オペレータは戻りませんプリミティブのために。
typeof"object"

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

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

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

を書き込むたびx.propertyに、異なるボックス化Stringオブジェクトが作成されます。


33
+1 typeof "foo"; // "string"typeof new String("foo"); // "object"
サンプソン

1
興味深いことに、私は文字列はJSのオブジェクトだと思っていました。
Cameron Martinが

1
@Sarfraz:ほとんどすべて。忘れてはいけないnullundefined

2
if( Object(a) !== a ) { //it's a primitive }
エサイリヤ2012年

1
Javaにはプリミティブがあります/ .Netにはありません
Marcelo De Zen

34

使用して===

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

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


3
new String("foo") === new String("foo")is false:-P
ロケットハズマット

10

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

を使用するとnewオブジェクトを操作したいという希望を明示的に表現できます。それはあなたにとって驚くべきことかもしれませんが、これは:

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

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

あなたがおそらく使いたいのは変換です:

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

...そして、それはtrue結果として、期待通りにあなたにあなたを与えるでしょう、それであなたはあなたの平等でfoos永遠に喜びそして繁栄することができます。)


2
これの使用についての簡単な質問。'new'キーワードなしでString(コンストラクタ?)を呼び出しています。これは、Stringコンストラクタ内で割り当てられたプロパティでスコープを汚染することを意味しませんか?または、コンストラクターがネイティブコードであるため、それは起こりませんか?つまり、String関数に「this.a = 1;」が含まれているとします。-それはあなたの関数/オブジェクトは、現在のプロパティA = 1だろう意味
マイケル・バトラー

それぞれの「ボクシングコンストラクター」関数は、最初にそのコンテキストをチェックします(ただし、「新しいもの」(つまり、プロトタイプオブジェクト)でない場合は、すぐに変換メソッドに切り替えます。toString()たとえば、Stringの場合はメソッドになります。
raina77ow


2

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'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.