在 JavaScript 中使用 == 的相等对象字符串

Equality object-String using == in JavaScript

我正在处理 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?,这道题没有把比较大小写处理成字符串!

==运算符表示等于转换。

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

From MDN:

Equality (==)

The equality operator converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.

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

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

[] == []也是如此。每个 [] 创建一个新的空数组,然后比较对它们的引用。

但是,当你将它们与 materials_3 进行比较时,它是一个 string (使用 ==,JS 将调用 valueOf() 在其他数组上将它们转换为原始值。由于从 valueOf() 编辑的值 return 也不是原始值,因此它将调用 toString(),即 returns "Hydrogen,Helium,Lithium"。由于字符串是基本类型,现在将按值和 return true.

进行比较

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

JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to invoke the valueOfmethod yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.

By default, the valueOfmethod is inherited by every object descended from Object. Every built-in core object overrides this method to return an appropriate value. If an object has no primitive value, valueOfreturns the object itself.

您可以在此处看到实际效果:

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);

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

所以在你的情况下,

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

案例二:同案例一

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