简体   繁体   中英

JS: weird object comparison behavior

Given this code:

 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 

Why does double-equals comparison return true when using the name variable, but not an object literal?

First, I thought that maybe it's because the objects have the same memory address, but as one can see it's not true.

Moreover, if we turn things upside-down and define the variable inside the function, the comparison returns false ! (It is not shown in the code but you can check it out)

I'm seriously confused and will appreciate the explanation.

EDIT: Here is where I have tested the code. Nodejs and browser console in Chrome give me the regular results, how it should be. So maybe it is something about the interpreter.

You assume that Javascript will perform the comparision with == as you are thinking of it in your mind, but it is not. But as this is a custom object you can't expect Javascript to hand you a custom implementation out of the box. You should implement it yourself.

The only case where this would work is when you use the === operator to check whether the object are the same but by their memory address, thus skipping any custom-object-data-based comparison whatsoever.

The problem here is the use of the word name for your variable.

In a browser, the window object has a name property that must always be a string. If you try to assign something to it that is not a string, it will be converted to one.

Then, when you compare an object with a string, the object will also be converted and the two strings compared. This is why you see it sometimes return true. Example:

 // 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. 

Change the name of the variable to anything else, or use let or const , and the problem should disappear:

 // 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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM