为什么[1,2,3]在Javascript中不等于它自己?

时间:2011-09-06 03:30:09

标签: javascript

我今天在Javascript中使用数组并注意到这个小宝石:

alert([1, 2, 3] == [1, 2, 3]); //alerts false

令我感到奇怪的是阵列不等于它自己。

但后来我注意到了这一点,甚至更奇怪了:

alert([1, 2, 3] == "1,2,3");  //alerts true

?!?!?!?!?

为什么世界上[1, 2, 3]不是==本身,而是==字符串?

我发现== not the same===。{{1}}。即便如此,邪恶可能会导致Javascript先生做出如此奇怪的事情?

6 个答案:

答案 0 :(得分:15)

好的,首先你需要了解javascript如何处理程序中的值。您创建的所有变量仅仅是引用到存储该对象的内存中的位置。因此,当您这样做时:

alert( [1,2,3] == [1,2,3] );

......它做了三件事:

  1. 将数组([1,2,3])放到堆上
  2. 将另一个数组([1,2,3])放到堆上(注意它将具有不同的内存位置)
  3. 比较两个参考文献。它们指向内存中不同位置的不同对象,因此被认为是不相等的。
  4. 您可以通过运行此代码来检查某些理智的行为:

    var a = [1,2,3];
    var b = a;
    alert (a == b)   // Result is true. Both point to the same object.
    

    现在提出有关字符串的问题

    当你使用==运算符尝试将两个操作数转换为相同类型时(恶行......我知道......)

    当它执行此操作时,它决定在进行比较之前将两者都转换为字符串(因此结果实际为"1,2,3" === "1,2,3",其结果为真。

    我不能给你一个完整的图片,因为很少有人了解JavaScript的疯狂的每一个细微差别,但希望这清除了一些迷雾。

答案 1 :(得分:4)

对于第一部分,您创建了两个不同的对象,因为数组只是对象,并且由于您创建了两个对象,因此它们都是唯一的。

答案 2 :(得分:4)

  

==运营商

     

[..]如果任一操作数是一个字符串,则另一个操作数将转换为字符串(如果可能)。 [..]如果两个操作数都是对象,则JavaScript比较内部引用,当操作数引用内存中的同一对象时,它们是相等的。

     

https://developer.mozilla.org/en/JavaScript/Reference/Operators/Comparison_Operators

也就是说,[1, 2, 3]转换为字符串等于"1,2,3"。但是,一个数组对象不等于另一个数组对象。

答案 3 :(得分:2)

第一次比较失败,因为两个对象的基本比较将检查它们是否在字面上是相同的引用对象,而不是两个对象具有相同的值。如果您希望比较两个数组,则必须循环使用这些值。

function arrayCompare(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  for (var i = 0, len = arr1.length; i < len; i++) {
    if (arr1[i] !== arr2[i]) return false;
  }
  return true;
}

请记住,这不是递归比较,因此它只适用于原始值数组。

第二个比较有效,因为==会尝试强制参数的类型,当你将数组转换为字符串时,就是结果。

[1,2,3].toString() === '1,2,3'

答案 4 :(得分:1)

两个Array对象是不同的,因此在使用==比较时不相等。要比较它们,你需要循环,检查两者中的索引是否相同(如果元素Array也是Object s,则递归。

第二个是因为Array隐含地调用了toString(),其返回'1,2,3'(尝试)。

这是因为根据ECMAScript中==(非严格)比较的规则,左手操作符被强制转换为String==进行类型转换)。

答案 5 :(得分:1)

因为==只强制,如果必须才能获得相同的类型(例如,仅当操作数的类型不同时)。做的时候

alert([1, 2, 3] == [1, 2, 3]); //alerts false

......不需要强制;两者都是对象。它们不是相同的对象,因此它是false。人们认为==是&#34;胁迫&#34;等式运算符,它是,但关键是它只强制,如果它必须

但是在做

alert([1, 2, 3] == "1,2,3");  //alerts true

...涉及不同类型的操作数:字符串和对象。所以强制就完成了。在这种情况下,对象被强制转换为字符串,就像使用String(obj)一样,它会调用其默认的toString行为,对于数组而言.join()join","默认为"1,2,3"作为分隔符,因此生成的字符串与Running: Name Value ---- ----- PSVersion 5.1.15063.608 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.15063.608 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 匹配。 (您可以找到对象被强制转换为字符串in the specification的完整逻辑。)