【问题标题】:JS: weird object comparison behaviorJS:奇怪的对象比较行为
【发布时间】:2018-06-22 18:05:06
【问题描述】:

鉴于此代码:

const name = { name: 'amy' };

function greet(person) {
    if (person == { name: 'amy' }) {
        return 'hey amy';
    } else {
        return 'hey there';
    }
}

console.log(
    greet(name)  // 'hey amy'
);

console.log(
    greet({ name:'amy' })  // 'hey there'
);

console.log(name == { name: 'amy' });  // true

console.log(name === { name: 'amy' });  // false

console.log(Object.is(name, { name: 'amy' }));  // false

为什么在使用name 变量时,双等号比较返回true,而不是对象字面量?

首先,我认为这可能是因为对象具有相同的内存地址,但正如我们所看到的那样,这不是真的。

此外,如果我们颠倒过来并在函数内部定义变量,则比较返回false! (代码中没有显示,但可以查看)

我很困惑,并会感谢您的解释。

编辑: Here 是我测试代码的地方。 Chrome 中的 Nodejs 和浏览器控制台给了我常规的结果,它应该是怎样的。所以也许这与解释器有关。

【问题讨论】:

  • 我看到你提到的不同结果。 (只是预期的。)

标签: javascript object variables comparison


【解决方案1】:

这里的问题是你的变量使用了name这个词。

在浏览器中,window 对象具有必须始终为字符串的name 属性。如果您尝试为其分配一些不是字符串的内容,它将被转换为一个。

然后,当您将一个对象与一个字符串进行比较时,该对象也将被转换并比较两个字符串。这就是为什么您有时会看到它返回 true 的原因。示例:

// This will end up being assigned to window.name, and will be converted to a string.
var name = {name: "amy"}
console.log(name) // [object Object]

// Then, when you compare that to another object using ==, the object will also be converted to string.
console.log(name == {name: "amy"}) // true, because the string [object Object] is equal to itself.

把变量名改成别的,或者用let或者const,问题应该就消失了:

// This will end up being assigned to window.other, but isn't converted to string
var other = {name: "amy"}
console.log(other) // {"name": "amy"}

// Now, both are objects, and unless they are the exact same object, comparing two objects is always false.
console.log(other == {name: "amy"}) // false, no two distinct objects are ever equal

// Using let will not assign this variable to window.
let name = {name: "amy"}
console.log(name) // {"name": "amy"}

// Again, now we compare two distict objects, which always results in false.
console.log(name == {name: "amy"}) // false

【讨论】:

  • 哇!更改名称已达成交易!非常感谢。但是,使用 letconst 以及 name 变量名会导致同样的奇怪行为!
  • 您的代码是否正在经历将let/const 转换为var 的转换步骤?如您所见,letconst 应该修复它,但可能在您运行它的环境中行为不同。但我怀疑它以某种方式被转换为var
  • 哦...无法检查,很可能确实如此。但是在浏览器中检查时,letconst 的行为与您所说的一样。再次感谢!
【解决方案2】:

您假设 Javascript 将执行与 == 的比较,正如您在脑海中所想的那样,但事实并非如此。但由于这是一个自定义对象,您不能指望 Javascript 为您提供开箱即用的自定义实现。你应该自己实现它。

唯一可行的情况是当您使用=== 运算符检查对象是否相同但通过它们的内存地址,从而跳过任何custom-object-data-based 比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 2013-12-24
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多