100

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

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

是错误的,与此相同:

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

当然:

f == g; // true

那么是否建议始终使用 == 进行字符串比较,或者始终在比较之前将变量转换为字符串?

4

5 回答 5

127

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

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

===运算符对原语和对象的行为不同。
比较原语(相同类型)时,===如果它们都具有相同的值,则返回 true。

比较对象时,===仅当它们引用同一个对象时才会返回 true(通过引用进行比较)。因此,new String("a") !== new String("a").

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


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

当您尝试访问原始属性(将其用作对象)时,Javascript 语言会将其装箱到对象中,每次都会创建一个新对象。这在规范中有所描述。

这就是为什么不能将属性放在原语上的原因:

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

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

于 2012-06-08T15:39:56.050 回答
34

使用===,

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

  • 如果它们的类型和值相同,则一个基元与另一个基元相比是相等的。

于 2012-06-08T15:40:26.397 回答
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)

于 2012-06-08T15:51:26.120 回答
4

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

于 2012-06-08T15:40:24.977 回答
2

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

> "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'
于 2012-06-08T18:47:56.257 回答