可能重复:
Why does (“foo” === new String(“foo”)) evaluate to false in JavaScript?
超过here我听到了最好使用非类型强制字符串比较的建议,但在Chrome中,我发现了一些奇怪的东西:
var t1 = String("Hello world!");
var t2 = new String("Hello world!");
var b1 = (t1==t2); // true
var b2 = (t1===t2); // false
这是标准行为吗?如果是这样,t1和t2各自的类型是什么?感谢。
答案 0 :(得分:9)
如果不对String使用“new
”关键字,则会得到一个原始字符串。
如果使用“new
”关键字,则会得到一个字符串对象而不是原始对象。
当您使用 ==
时,它会尝试转换为类似的类型,因此它可以相等。
如果您使用 ===
,则不会转换,因此对象不能等于基元。
答案 1 :(得分:6)
以下是解释
typeof String("Hello world!");
"string"
和
typeof new String("Hello world!");
"object"
当你使用===
时,它会关注类型,因此返回false
答案 2 :(得分:5)
String
将其参数转换为string
。 String
,作为构造函数调用,创建一个原型为String
函数的对象。 (检查James's Answer以获取相关的ECMAScript规范部分。)
这确实令人困惑。
两个相等的运算符实际上做了很多不同的事情。从ECMA-262, v 5.1 document,===
执行:
- 如果
Type(x)
与Type(y)
不同,请返回false
。- 如果
Type(x)
为Undefined
,请返回true
。- 如果
Type(x)
为Null
,请返回true
。- 如果
Type(x)
为Number
,则为 一个。如果x
为NaN
,请返回false
湾如果y
为NaN
,请返回false
C。如果x
与Number
的{{1}}值相同,请返回y
。
d。如果true
为x
且+0
为y
,请返回-0
。
即如果true
为x
且-0
为y
,请返回+0
。
F。返回true
。- 如果
false
为Type(x)
,则如果String
和true
完全相同的字符序列(相应的长度和相同字符),则返回x
位置);否则,请返回y
。- 如果
false
为Type(x)
,如果Boolean
和true
同时为x
或y
,则返回true
;否则,请返回false
。- 如果
醇>false
和true
引用同一个对象,则返回x
。否则,请返回y
。
false
确实:
- 如果
==
与Type(x)
相同,则为 一个。如果Type(y)
为Type(x)
,请返回Undefined
湾如果true
为Type(x)
,请返回Null
C。如果true
为Type(x)
,则为 一世。如果Number
为x
,请返回NaN
II。如果false
为y
,请返回NaN
III。如果false
与x
的{{1}}值相同,请返回Number
。
IV。如果y
为true
且x
为+0
,请返回y
。
v。如果-0
为true
且x
为-0
,请返回y
。
六。返回+0
。
d。如果true
为false
,则如果Type(x)
和String
完全相同的字符序列(相应位置的相同长度和相同字符),则返回true
。否则,请返回x
即如果y
为false
,则如果Type(x)
和Boolean
同时为true
或x
,则返回y
。否则,请返回true
F。如果false
和false
引用同一个对象,则返回true
。否则,请返回x
。- 如果
y
为空并且false
未定义,请返回x
。- 如果
y
未定义且true
为空,请返回x
。- 如果
y
为true
且Type(x)
为Number
,请返回比较结果
Type(y)
。- 如果
String
为x == ToNumber(y)
且Type(x)
为String
,请返回比较结果
Type(y)
。- 如果
Number
为ToNumber(x) == y
,请返回比较结果Type(x)
。- 如果
Boolean
为ToNumber(x) == y
,请返回比较结果Type(y)
。- 如果
Boolean
为x == ToNumber(y)
或Type(x)
且String
为Number
,请返回比较结果Type(y)
。- 如果
Object
为x == ToPrimitive(y)
且Type(x)
为Object
或Type(y)
,请返回比较结果String
。- 返回
醇>Number
。
请注意,在规范中,原始字符串对象的ToPrimitive(x) == y
为false
,而任何对象(包括Type
对象)的类型为String
。
对于String
,相关行为Object
:对象的===
不同,因此会返回#1
。
Type
相关行为false
:==
为#8
(x
),String
为"Hello world!"
(包含字符串y
的{{1}}对象)。因此,进行了比较Object
。 String
最终调用对象的"Hello world!"
方法,或者如果该方法不存在,则x == ToPrimitive(y)
方法。在这种情况下,ToPrimitive
对象的valueOf
方法返回对象包含的原语toString
。因此,再次完成相等操作,这次是在包含相同文本的两个原始String
之间,由于valueOf
而返回string
。
引擎盖下的JavaScript有点混乱......
编辑:请注意,如果比较两个对象,则不会应用任何转化,而是应用规则string
。因此,由于规范,我能够正确预测以下代码的输出:
true
编辑:我想补充一点,这些区别甚至会被更隐式的类型转换所模糊。例如,以下工作:
#1.d
但这不是因为#1.f
是一个对象(就像在Python中一样):
> new String("hi") == new String("hi")
false
但是,因为.
operator does a conversion从原始> ("hi").toString()
"hi"
类型到字符串"hi"
类型(创建新的字符串对象),其> typeof "hi"
"string"
方法然后被召唤。
答案 3 :(得分:3)
此行为在ECMAScript 5 specification, 15.5.1 and 15.5.2:
中详细说明当
String
作为函数而不是构造函数调用时,它会执行类型转换。...
返回由
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
答案 4 :(得分:1)
这种情况正在发生,因为==
运算符仅检查值是否相同,而===
检查值和类型。 new String("Hello world!")
实际上并未提供string
类型,而是object
,而String("Hello world!")
实际上是string
。
答案 5 :(得分:0)
第一个示例String("Hello world!)"
创建一个原始字符串,而第二个示例new String("Hello world!")
创建一个String对象。