String
,作为函数调用,将其参数转换为 a string
。String
,作为构造函数调用,创建一个原型为String
函数的对象。(查看相关 ECMAScript 规范部分的James 答案。)
这确实令人困惑。
这两个相等运算符实际上做了非常不同的事情。从ECMA-262, v 5.1 文档中,===
可以:
- 如果
Type(x)
不同Type(y)
,则返回false
。
- 如果
Type(x)
是Undefined
,则返回true
。
- 如果
Type(x)
是Null
,则返回true
。
- 如果
Type(x)
是Number
,那么
a. 如果x
是NaN
,则返回false
。
湾。如果y
是NaN
,则返回false
。
C。如果x
与 的Number
值相同y
,则返回true
。
d。如果x
是+0
和y
是-0
,返回true
。
e. 如果x
是-0
和y
是+0
,返回true
。
F。返回false
。
- 如果
Type(x)
是String
,则返回true
ifx
和y
是完全相同的字符序列(长度相同,对应位置的字符相同);否则,返回false
。
- If
Type(x)
is Boolean
, return true
if x
and y
are both true
or both false
; 否则,返回false
。
- 返回
true
ifx
并y
引用同一个对象。否则,返回false
。
鉴于==
:
- 如果
Type(x)
与 相同Type(y)
,则
a。如果Type(x)
是Undefined
,则返回true
。
湾。如果Type(x)
是Null
,则返回true
。
C。如果Type(x)
是Number
,那么
我。如果x
是NaN
,则返回false
。
ii. 如果y
是NaN
,则返回false
。
iii. 如果x
与 的Number
值相同y
,则返回true
。
iv. 如果x
是+0
和y
是-0
,返回true
。
v. 如果x
是-0
并且y
是+0
,返回true
。
六。返回false
。
d。如果Type(x)
is String
,然后返回true
ifx
和y
是完全相同的字符序列(相同的长度和相同的字符在相应的位置)。否则,返回false
。
e. 如果Type(x)
是Boolean
,则返回true
ifx
和y
are bothtrue
或 both false
。否则,返回false
。
F。返回true
ifx
并y
引用同一个对象。否则,返回false
。
- 如果
x
为 nully
且未定义,则返回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
is a String
( "Hello world!"
) and y
is an Object
(The String
object contains the string "Hello world!"
)。这样就进行了比较x == ToPrimitive(y)
。ToPrimitive
最终调用valueOf
对象的方法,或者如果该方法不存在,则调用该toString
方法。在这种情况下,String
对象的valueOf
方法返回string
对象包含的原语。因此,相等操作再次完成,这次是在两个string
包含相同文本的原始 s之间,true
由于#1.d
.
JavaScript 在底层有点混乱......
编辑:请注意,如果比较两个对象,则不应用转换,而是应用规则#1.f
。因此,多亏了规范,我能够正确预测以下代码的输出:
> new String("hi") == new String("hi")
false
编辑:只是想我会补充一点,这些区别被更隐式的类型转换进一步模糊了。例如,以下工作:
> ("hi").toString()
"hi"
但这不是因为"hi"
是一个对象(就像在 Python 中一样):
> typeof "hi"
"string"
而是因为.
运算符 将原始类型转换string
为字符串Object
类型(创建一个新的字符串对象),toString
然后调用其方法。