什么时候JavaScript字符串不是字符串?

Nat*_*nax 8 javascript

可能重复:
为什么("foo"=== new String("foo"))在JavaScript中评估为false?

这里我发现了最好使用非类型强制字符串比较的建议,但在Chrome中,我发现了一些奇怪的东西:

var t1 = String("Hello world!");
var t2 = new String("Hello world!");
var b1 = (t1==t2); // true
var b2 = (t1===t2); // false
Run Code Online (Sandbox Code Playgroud)

这是标准行为吗?如果是这样,t1和t2各自的类型是什么?谢谢.

gra*_*ing 9

如果不对newString 使用" "关键字,则会得到一个原始字符串.

如果使用" new"关键字,则会得到一个字符串对象而不是原始对象.

当你使用==它时会尝试转换为类似的类型,因此它可以是相同的.

如果使用===,则不会转换,因此对象不能等于基元.


Ibu*_*Ibu 6

这是解释

typeof String("Hello world!");
"string"
Run Code Online (Sandbox Code Playgroud)

和:

typeof new String("Hello world!");
"object"
Run Code Online (Sandbox Code Playgroud)

当你使用===它时要注意类型,所以它返回false


Cla*_*diu 5

String,作为函数调用,将其参数转换为a string.String,作为构造函数,创建一个原型是String函数的对象.(查看James的答案,了解相关的ECMAScript规范部分.)

这确实令人困惑.

两个相等运算符实际上做了很多不同的事情.从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.
    湾 如果yNaN,请返回false.
    C.如果x是相同的Numbery,则返回true.
    d.如果x+0,y-0,返回true.
    即 如果x-0,y+0,返回true.
    F.返回false.
  5. 如果Type(x)String,则返回trueif xy完全相同的字符序列(相应位置的相同长度和相同字符); 否则,返回false.
  6. 如果Type(x)Boolean,则返回trueif xyboth两者true或两者false; 否则,返回false.
  7. 返回trueif xy引用同一个对象.否则,返回false.

==做:

  1. 如果Type(x)是相同的Type(y),那么
    a.如果Type(x)Undefined,请返回true.
    湾 如果Type(x)Null,请返回true.
    C.如果Type(x)Number,那么
       我.如果xNaN,请返回false.
       II.如果yNaN,请返回false.
       III.如果x是相同的Numbery,则返回true.
       IV.如果x+0,y-0,返回true.
       v.如果x-0,y+0,返回true.
       六.返回false.
    d.如果Type(x)String,则返回trueif xy完全相同的字符序列(相应位置的相同长度和相同字符).否则,返回false.
    即 如果Type(x)Boolean,则返回trueif xyboth两者true或两者false.否则,返回false.
    F.返回trueif xy引用同一个对象.否则,返回false.
  2. 如果x为null y且未定义,则返回true.
  3. 如果x未定义且y为null,则返回true.
  4. 如果Type(x)NumberType(y)String,返回比较的结果
    x == ToNumber(y).
  5. 如果Type(x)StringType(y)Number,返回比较的结果
    ToNumber(x) == y.
  6. 如果Type(x)Boolean,则返回比较结果ToNumber(x) == y.
  7. 如果Type(y)Boolean,则返回比较结果x == ToNumber(y).
  8. 如果Type(x)是两种StringNumberType(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:x是a String("Hello world!")并且yObject(String包含字符串的对象"Hello world!").因此进行了比较x == ToPrimitive(y).ToPrimitive最终调用valueOf对象的方法,或者如果该方法不存在,则该toString方法.在这种情况下,String 对象valueOf方法返回string对象包含的原语.因此,相等操作再次完成,这次是在string包含相同文本的两个原语之间,这归结为true感谢#1.d.

引擎盖下的JavaScript有点混乱......


编辑:请注意,如果比较两个对象,则不应用任何转换,而是应用规则#1.f.因此,由于规范,我能够正确预测以下代码的输出:

> new String("hi") == new String("hi")
false
Run Code Online (Sandbox Code Playgroud)

编辑:我想补充一点,这些区别甚至通过更隐式的类型转换进一步模糊.例如,以下工作:

> ("hi").toString()
"hi"
Run Code Online (Sandbox Code Playgroud)

但那不是因为"hi"是一个对象(比如Python):

> typeof "hi"
"string"
Run Code Online (Sandbox Code Playgroud)

但是,因为.操作符 执行从基本string类型到字符串Object类型的转换(创建新的字符串对象),toString然后调用其方法.