在比较字符串值时,我会一直开始使用===(三等号,严格比较),但现在我发现
"foo" === new String("foo")
是假的,与此相同:
var f = "foo", g = new String("foo");
f === g; // false
当然:
f == g; // true
所以建议总是使用==进行字符串比较,或者总是在比较前将变量转换为字符串?
答案 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'