在 JavaScript 中使用 == 的相等对象字符串 [重复]

Posted

技术标签:

【中文标题】在 JavaScript 中使用 == 的相等对象字符串 [重复]【英文标题】:Equality object-String using == in JavaScript [duplicate] 【发布时间】:2018-10-16 09:43:10 【问题描述】:

我正在用 javascript 处理一个奇怪的情况,

我知道 JS 的奇怪时刻(像这样)一点也不奇怪,只是代码完全可以预测并完全按照指定的方式工作。

var materials_1 = ['Hydrogen', 'Helium', 'Lithium'];
var materials_2 = ['Hydrogen', 'Helium', 'Lithium'];
var materials_3 = "Hydrogen,Helium,Lithium";

console.log(materials_1 == materials_3); //True
console.log(materials_2 == materials_3); //True
console.log(materials_1 == materials_2); //False

console.log([] == []);  //False

但是,在这种平等比较中使用== 时,谁能给我一个详细的解释?

谢谢你的光。

注意:我检查了How to compare arrays in JavaScript?,这个问题没有用字符串处理比较大小写!

【问题讨论】:

还有Which equals operator (== vs ===) should be used in JavaScript comparisons? @MohammadUsman,我检查了这个问题!我的问题是更面向对象字符串,没有比较运算符! ***.com/questions/7314635/… 【参考方案1】:

== 运算符表示与转换相等。

当与两种不同的类型一起使用时,一种(或两种)将被强制转换为通用类型以进行比较。这就是前两个测试用例(数组 == 字符串)发生的情况。

From MDN:

平等(==)

相等运算符转换操作数,如果它们是 不属于同一类型,则应用严格比较。如果两个操作数 是对象,然后 JavaScript 比较内部引用 当操作数引用内存中的同一个对象时相等。

所以,当比较两个对象时(数组是对象),它们已经是相同的类型,所以对象reference会与另一个对象进行比较。对于对象,比较的不是数据,而是内存中的实际对象,因此比较两个变量以查看它们是否指向相同的内存位置,在您的情况下,它们没有。

【讨论】:

【参考方案2】:

即使materials_1materials_2 包含相同的string 值,它们实际上也是两个不同的Arrays。当你比较它们时,你实际上是在比较引用,这就是为什么不管数组的内容如何,​​这样的东西总是false

这同样适用于[] == []。每个[] 都会创建一个新的空数组,然后您比较它们的引用。

但是,当您将它们与materials_3(即string)进行比较时(使用==,JS 将在其他数组上调用valueOf() 以将它们转换为原始数组价值。由于valueOf()返回的值也不是原始值,它会调用toString(),返回"Hydrogen,Helium,Lithium"。由于字符串是原语,现在将按值进行比较并返回true

您可以在 MDN 上找到有关 valueOf() 的更多信息:

JavaScript 调用valueOf 方法将对象转换为原始值。你很少需要自己调用valueOf方法; JavaScript 在遇到需要原始值的对象时会自动调用它。

默认情况下,valueOf 方法被从Object 继承的每个对象继承。每个内置核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,valueOf返回对象本身。

你可以在这里看到它的实际效果:

function ObjectWrapper(actualObject) 
  this.actualObject = actualObject || ;


ObjectWrapper.prototype.valueOf = function() 
  console.log('valueOf');
  
  return this.actualObject; // Not a primitive.
;

ObjectWrapper.prototype.toString = function() 
  console.log('toString');
  
  return this.actualObject.toString();
;

const foo = new ObjectWrapper([1, 2, 3]);
const bar = '1,2,3';

console.log(foo == bar);

【讨论】:

【参考方案3】:

当使用 == 运算符并且至少有一个操作数是原始的时,Javascript 会尝试将比较中的两个变量转换为相同的相似类型。 Reference

所以在你的情况下,

案例 1: materials_1 == materials_3 被处理为 materials_1.toString() == materials_3 (事实证明是真的)

案例2:同案例1

案例 3:这里的两个操作数都是相同的类型(即数组)。由于对象是基于引用进行比较的,它们显然具有不同的内存位置,因此它们不会相等。

【讨论】:

Javascript 尝试转换两个比较对象 不,对象不会被转换,只有基元会被转换。 如果只转换原语,则所讨论的情况 1 和 2 不应返回 true - 对吧? 我的意思是当它是一个对象和一个被比较的对象时你的陈述是不正确的(你写了 both 对象)。如果它是一个对象 == 基元,那么只有一个对象。 糟糕!我的错。感谢您纠正我。

以上是关于在 JavaScript 中使用 == 的相等对象字符串 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中对象的比较

JavaScript学习——JavaScript比较和 逻辑运算

如何确定两个 JavaScript 对象的相等性?

JavaScript判断对象是否相等

判断两个数组是不是相等

如何判断两个对象相等