为什么 ("foo" === new String("foo")) 在 JavaScript 中求值为 false?

IT技术 javascript object equality
2021-02-23 19:32:43

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

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

是假的,与此相同:

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

当然:

f == g; // true

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

5个回答

"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对象。

+1 typeof "foo"; // "string",typeof new String("foo"); // "object"
2021-04-21 19:32:43
有趣的是,我认为字符串是 JS 中的对象。
2021-04-25 19:32:43
Java 确实有原语 / .Net 没有
2021-05-15 19:32:43
if( Object(a) !== a ) { //it's a primitive }
2021-05-17 19:32:43
@Sarfraz:几乎所有东西。不要忘记nullundefined
2021-05-18 19:32:43

使用===,

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

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

new String("foo") === new String("foo")false:-P
2021-05-13 19:32:43

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

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

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永远与平等的人一起快乐和繁荣)

我想(但不能肯定)每个“装箱构造函数”函数首先检查其上下文 - 如果它不是“新的”(即原型对象),则立即切换到转换方法。例如,在 String 的情况下,这将是toString()方法。
2021-04-21 19:32:43
关于使用这个的快速问题。您正在调用 String (构造函数?)而没有 'new' 关键字。这是否意味着您将使用 String 构造函数中分配的任何属性污染范围?或者这不会发生,因为构造函数是本机代码?换句话说,假设 String 函数包含“this.a = 1;” -- 这意味着您的函数/对象现在将具有属性 a = 1。
2021-04-23 19:32:43

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

从 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'