8

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

ここで、非型強制文字列比較を使用するのが最善であるというアドバイスを受け取りましたが、Chrome で何か奇妙なことを発見しました。

var t1 = String("Hello world!");
var t2 = new String("Hello world!");
var b1 = (t1==t2); // true
var b2 = (t1===t2); // false

これは標準的な動作ですか?もしそうなら、t1 と t2 のそれぞれの型は何ですか? ありがとう。

4

6 に答える 6

9

String で" " キーワードを使用しない場合はnew、プリミティブ文字列が取得されます。

new" " キーワードを使用すると、プリミティブではなく文字列オブジェクトが取得されます。

使用==すると、同等の型に変換しようとするため、同等にすることができます。

を使用する===と、変換されないため、オブジェクトをプリミティブと等しくすることはできません。

于 2012-08-15T21:23:14.583 に答える
6

ここに説明があります

typeof String("Hello world!");
"string"

と:

typeof new String("Hello world!");
"object"

使う===と型に気をつけているのでfalseを返す

于 2012-08-15T21:23:12.340 に答える
5

Stringは関数として呼び出され、その引数を に変換しますstringStringコンストラクターとして呼び出され、プロトタイプがString関数であるオブジェクトを作成します。(関連する ECMAScript 仕様セクションについては、James の回答を確認してください。)

これは確かに紛らわしいです。

2 つの等値演算子は、実際には非常に異なることを行います。ECMA-262、v 5.1 ドキュメントから、次のことを===行います。

  1. Type(x)が と異なる場合はType(y)、 を返しfalseます。
  2. である場合Type(x)Undefined、 を返しtrueます。
  3. である場合Type(x)Null、 を返しtrueます。
  4. Type(x)の場合Number
    a. である場合xNaN、 を返しfalseます。
    b. である場合yNaN、 を返しfalseます。
    c. xが と同じNumber値の場合y、 を返しtrueます。
    d. とがである場合xは、 を返します。 e. とがである場合は、 を返します。 f. 戻る。+0y-0true
    x-0y+0true
    false
  5. Type(x)がの場合、とがまったく同じ文字シーケンス (対応する位置に同じ長さと同じ文字) である場合Stringに返されます。それ以外の場合は、 を返します。truexyfalse
  6. である場合Type(x)は、とが両方または両方である場合Booleanに返します。それ以外の場合は、 を返します。truexytruefalsefalse
  7. trueifxを返しy、同じオブジェクトを参照します。それ以外の場合は、 を返しfalseます。

一方==、:

  1. Type(x)が と同じ場合Type(y)
    a. である場合Type(x)Undefined、 を返しtrueます。
    b. である場合Type(x)Null、 を返しtrueます。
    c. Type(x)の場合Number
       i. である場合xNaN、 を返しfalseます。
       ii. である場合yNaN、 を返しfalseます。
       iii. xが と同じNumber値の場合y、 を返しtrueます。
       iv。とがである場合xは、 を返します。    v. であり、である場合は、を返します。    vi. 戻る。 d. もしも+0y-0true
    x-0y+0true
    false
    Type(x)isの場合、 とがまったく同じ文字シーケンス (対応する位置に同じ長さと同じ文字) である場合Stringに返されます。それ以外の場合は、 を返します。 e. である場合、とが両方または両方である場合に返します。それ以外の場合は、 を返します。 f. ifを返し、同じオブジェクトを参照します。それ以外の場合は、 を返します。truexyfalse
    Type(x)Booleantruexytruefalsefalse
    truexyfalse
  2. xが null でy未定義の場合は、 を返しtrueます。
  3. xが未定義でynull の場合は、 を返しtrueます。
  4. Type(x)isNumberType(y)isの場合String、比較の結果を返し
    x == ToNumber(y)ます。
  5. Type(x)isStringType(y)isの場合Number、比較の結果を返し
    ToNumber(x) == yます。
  6. Type(x)である場合Boolean、比較の結果を返しToNumber(x) == yます。
  7. Type(y)である場合Boolean、比較の結果を返しx == ToNumber(y)ます。
  8. Type(x)Stringまたは またはNumberType(y)ある場合Object、比較の結果を返しx == ToPrimitive(y)ます。
  9. Type(x)ObjectType(y)が または のいずれStringかである場合Number、比較の結果を返しToPrimitive(x) == yます。
  10. 戻るfalse

仕様ではType、プリミティブ文字列オブジェクトの はStringであるのに対し、任意のオブジェクト (オブジェクトを含むString)の型は であることに注意してくださいObject

関連する===行は#1:Typeオブジェクトの が異なるため、falseが返されます。

==関連する行は#8:xString( "Hello world!") でありyObject(String文字列を含むオブジェクト"Hello world!") です。したがって、比較x == ToPrimitive(y)が行われます。ToPrimitiveオブジェクトのメソッドを呼び出すvalueOfか、そのメソッドが存在しない場合はメソッドを呼び出しますtoString。この場合、String objectvalueOfメソッドはstring、オブジェクトに含まれるプリミティブを返します。したがって、今度stringは、同じテキストを含む 2 つのプリミティブの間で等価演算が再度行われ、 のtrueおかげで返され#1.dます。

JavaScript は、ボンネットの下で少し面倒です...


編集: 2 つのオブジェクトが比較される場合、変換は適用されず、ルール#1.fが適用されることに注意してください。したがって、仕様のおかげで、次のコードの出力を正しく予測できました。

> new String("hi") == new String("hi")
false

編集:これらの区別は、より暗黙的な型変換によってさらにぼやけていることを付け加えたいと思いました。たとえば、次のように動作します。

> ("hi").toString()
"hi"

しかし、それ"hi"はオブジェクトだからではありません (Python のように):

> typeof "hi"
"string"

むしろ、.演算子 はプリミティブ型から文字列型への変換(新しい文字列オブジェクトの作成) を行い、そのメソッドが呼び出されるためです。stringObjecttoString

于 2012-08-15T21:23:44.723 に答える
3

この動作は、ECMAScript 5 仕様、15.5.1 および 15.5.2 で詳しく説明されています。

Stringコンストラクターとしてではなく関数として呼び出されると、型変換が実行されます。

...

Stringによって計算された文字列値 (オブジェクトではない) を返しますToString(value)。が指定されていない場合valueは、空の文字列 "" が返されます。

したがってString("some string")、文字列値を作成します。

が式Stringの一部として呼び出されるとnew、コンストラクターになります。つまり、新しく作成されたオブジェクトを初期化します。

したがってnew String("some string")、オブジェクトのインスタンスを作成しStringます。


実際にあなたの質問に答えるには:

これは標準的な動作ですか?

はい、上記の理由により。

もしそうなら、t1とt2のそれぞれのタイプは何ですか

typeofこれは、オペレーターで確認できます。

console.log(typeof t1); //string
console.log(typeof t2); //object
于 2012-08-15T21:27:30.093 に答える
1

これは、==演算子が値が同じかどうかのみをチェックし、値===の両方をチェックするために発生します。は実際にはタイプが与えられていませんが、実際にはです。new String("Hello world!")stringobjectString("Hello world!")string

于 2012-08-15T21:24:44.770 に答える
0

最初の例String("Hello world!)"はプリミティブ文字列を作成し、2 番目の例new String("Hello world!")は String オブジェクトを作成します。

于 2012-08-15T21:23:30.203 に答える