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,则返回trueifx和y是完全相同的字符序列(长度相同,对应位置的字符相同);否则,返回false。
- If
Type(x)is Boolean, return trueif xand yare both trueor both false; 否则,返回false。
- 返回
trueifx并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,然后返回trueifx和y是完全相同的字符序列(相同的长度和相同的字符在相应的位置)。否则,返回false。
e. 如果Type(x)是Boolean,则返回trueifx和yare bothtrue或 both false。否则,返回false。
F。返回trueifx并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: xis a String( "Hello world!") and yis an Object(The Stringobject 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然后调用其方法。