【问题标题】:Why does ("foo" === new String("foo")) evaluate to false in JavaScript?为什么 ("foo" === new String("foo")) 在 JavaScript 中评估为 false?
【发布时间】:2012-06-12 16:38:48
【问题描述】:

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

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

是假的,和这个一样:

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

当然:

f == g; // true

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

【问题讨论】:

  • 可能是因为foo 是纯字符串,new String("foo") 是对象字符串
  • 建议不要使用new String(完全没有意义)创建字符串,而不要使用==
  • 为什么有人想首先在 Javascript 中使用像 new String("foo") 这样的构造?我从未在代码中看到过这样的代码,即 jQuery...
  • 收到“字符串”参数后,您可以使用String(obj) 将装箱字符串转换为原语。 ("foo" === String(new String("foo"))) === true

标签: javascript object equality


【解决方案1】:

"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 typeof "foo"; // "string", typeof new String("foo"); // "object"
  • 有趣,我认为字符串是 JS 中的对象。
  • @Sarfraz:几乎所有东西。不要忘记nullundefined
  • if( Object(a) !== a ) { //it's a primitive }
  • Java 有原语/.Net 没有
【解决方案2】:

使用===

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

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

【讨论】:

  • new String("foo") === new String("foo")false :-P
【解决方案3】:

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

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

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

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

你可能想要使用的是conversion

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

... 正如预期的那样,这将为您提供true,因此您可以永远与平等的foos 一起欢乐和繁荣。 )

【讨论】:

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

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

【讨论】:

    【解决方案5】:

    来自 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'

    【讨论】:

      猜你喜欢
      • 2017-10-27
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多