为什么(“foo”=== new String(“foo”))在JavaScript中评估为false?

时间:2012-06-08 15:38:06

标签: javascript object equality

在比较字符串值时,我会一直开始使用===(三等号,严格比较),但现在我发现

"foo" === new String("foo")

是假的,与此相同:

var f = "foo", g = new String("foo");
f === g; // false

当然:

f == g; // true

所以建议总是使用==进行字符串比较,或者总是在比较前将变量转换为字符串?

5 个答案:

答案 0 :(得分:126)

"foo"是字符串原语。 (这个概念在C#或Java中不存在)

new String("foo")是盒装字符串对象。

===运营商behaves differently on primitives and objects 比较基元(相同类型)时,===如果它们具有相同的值,则返回true。

比较对象时,===只有在引用同一对象时才会返回true(通过引用进行比较)。因此,new String("a") !== new String("a")

在您的情况下,===返回false,因为操作数的类型不同(一个是基元,另一个是对象)。


原语根本不是对象。
对于基元,typeof运算符不会返回"object"

当您尝试访问基元的属性(将其用作对象)时,Javascript语言会将其设置为对象,每次都创建一个新对象。这在specification

中有所描述

这就是你不能在基元上放置属性的原因:

var x = "a";
x.property = 2;
alert(x.property) //undefined

每次撰写x.property时,都会创建一个不同的盒装String对象。

答案 1 :(得分:34)

使用===

  • 除了对自身的另一个引用之外,对象永远不会等于任何东西。

  • 如果原语与其他原语相比,如果它们的类型和值相同,则它是相等的。

答案 2 :(得分:10)

new这个词在这里是个罪犯(像往常一样,我可以说)......

当您使用new时,您明确表达了使用对象的愿望。你可能会感到惊讶,但是这个:

var x = new String('foo');
var y = new String('foo');
x === y; 

...会给你一个强大的false。这很简单:比较不是对象的内部,而是对象的引用。当然,它们并不相同,因为创建了两个不同的对象。

您可能想要使用的是转换

var x = String('foo');
var y = String('foo');
x === y;

......这将使你按照预期true作为结果,这样你就可以永远地与你的平等foos一起欢乐和繁荣。 )

答案 3 :(得分:4)

foo是纯字符串,new String("foo")是对象字符串

答案 4 :(得分:2)

从node.js REPL(如果安装了命令行中的“node”):

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'