JavaScript 字符串何时不是字符串? [复制]
Posted
技术标签:
【中文标题】JavaScript 字符串何时不是字符串? [复制]【英文标题】:When is a JavaScript String not a string? [duplicate] 【发布时间】:2012-08-12 05:34:48 【问题描述】:可能重复: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 各自的类型是什么?谢谢。
【问题讨论】:
您可以使用typeof
运算符进行检查。并阅读spec 了解完整详情。
【参考方案1】:
如果您不将“new
”关键字与字符串一起使用,则会得到一个原始字符串。
如果你使用“new
”关键字,你会得到一个字符串对象而不是原始对象。
当您使用 ==
时,它会尝试转换为可比较的类型,因此可以相等。
如果你使用===
,它不会转换,所以一个对象不能等于一个基元。
【讨论】:
+1 另外:String
是一种 特殊 类型的对象,其中定义了 [ToPrimitive]。没有其他自定义对象可以与 ==
(使用上述字符串值)相等。【参考方案2】:
这里是解释
typeof String("Hello world!");
"string"
还有:
typeof new String("Hello world!");
"object"
当你使用 ===
时,它会注意类型,所以它返回 false
【讨论】:
这不是解释,但它显示了为什么它们不相等。解释将说明为什么new String
和 String
创建不同的类型。
是的,但您没有解释为什么==
正在评估true
而===
评估为false
。解释是==
比较值,而===
比较值和类型。一个是字符串,另一个是对象,这就是为什么===
是false
。
这也不能解释为什么==
有效(在JavaScript 中==
对它有意义的对象很少).. 只是为什么===
无效。【参考方案3】:
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
值相同y
,则返回true
。 d。如果x
是+0
并且y
是-0
,则返回true
。 e.如果x
是-0
而y
是+0
,则返回true
。 F。返回false
。 如果Type(x)
是String
,则返回true
如果x
和y
是完全相同的字符序列(相同的长度和对应位置的相同字符);否则,返回false
。 如果Type(x)
是Boolean
,如果x
和y
都是true
或者都是false
,则返回true
;否则,返回false
。 如果x
和y
引用同一个对象,则返回true
。否则,返回false
。
而==
会:
如果
Type(x)
与Type(y)
相同,则 一种。如果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)
是String
,那么如果x
和y
是完全相同的字符序列(相同的长度和对应位置的相同字符),则返回true
。否则,返回false
。 e.如果Type(x)
是Boolean
,如果x
和y
都是true
或两者都是false
,则返回true
。否则,返回false
。 F。如果x
和y
引用同一个对象,则返回true
。否则,返回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
是Object
(包含字符串String
的对象"Hello world!"
) .因此进行了比较x == ToPrimitive(y)
。 ToPrimitive
最终调用对象的 valueOf
方法,或者如果该方法不存在,则调用 toString
方法。在这种情况下,String
object 的 valueOf
方法返回对象包含的原始 string
。因此相等操作再次完成,这次是在两个包含相同文本的原始string
s 之间,由于#1.d
而返回true
。
JavaScript 在底层有点混乱......
编辑:请注意,如果比较两个对象,则不适用任何转换,而是适用规则 #1.f
。因此,感谢规范,我能够正确预测以下代码的输出:
> new String("hi") == new String("hi")
false
编辑:我只是想补充一点,这些区别被更隐式的类型转换进一步模糊了。例如,以下工作:
> ("hi").toString()
"hi"
但这并不是因为"hi"
是一个对象(就像在 Python 中一样):
> typeof "hi"
"string"
而是因为.
operatordoes a conversion从原始string
类型到字符串Object
类型(创建一个新的字符串对象)然后调用其toString
方法。
【讨论】:
您缺少===
的 6. 和 7. 的一部分,而且我认为引用块比代码块更具可读性。
谢谢,但我将如何缩进这些行?添加了 6+7 的缺失位
好问题。 +1 完成。我正在检查缩进和保留编号的最简单方法。
嗯,这样就够可读了,blockquote 看起来像一堵文字墙,至少像这样它更彩色。 =]
人们总是可以阅读您链接中的格式化版本。
我认为缩进和code
提示是正确的。请检查。【参考方案4】:
此行为在ECMAScript 5 specification, 15.5.1 and 15.5.2中有详细说明:
当
String
作为函数而不是构造函数调用时,它会执行类型转换。...
返回由
ToString(value)
计算的字符串值(不是String
对象)。如果未提供value
,则返回空字符串“”。
所以String("some string")
创建了一个字符串值。
当
String
作为new
表达式的一部分被调用时,它是一个构造函数:它初始化新创建的对象。
所以new String("some string")
创建了String
对象的一个实例。
真正回答你的问题:
这是标准行为吗?
是的,原因如上所述。
如果有,t1和t2分别是什么类型
您可以使用typeof
操作符进行检查:
console.log(typeof t1); //string
console.log(typeof t2); //object
【讨论】:
+1,还有new String("Hello world!").toString() === String("Hello world!")
【参考方案5】:
发生这种情况是因为==
运算符只检查值是否相同,而===
则同时检查值 和 类型。 new String("Hello world!")
实际上并没有被赋予 string
类型,它是 object
,而 String("Hello world!")
实际上是 string
。
【讨论】:
【参考方案6】:第一个示例String("Hello world!)"
创建一个原始字符串,而第二个示例new String("Hello world!")
创建一个字符串对象。
【讨论】:
以上是关于JavaScript 字符串何时不是字符串? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Scikit 中应用二元分类器来学习何时属性是字符串(不是 int 或 float)
Javascript:设置 location.href 与位置
Javascript:设置 location.href 与位置