5

Here is one of the questions in JavaScript online-test before job interview:

function F(){};

var a = new F();
var b = new F();

Q: How to make comparison a == b to be true? (e.g. console.log(a == b) // true)

I answered that it's impossible because a and b are two different instances of F and equal comparison in JS in case of non-primitives compares reference.

But some time ago I've read article "Fake operator overloading in JavaScript" by Axel Rauschmayer: http://www.2ality.com/2011/12/fake-operator-overloading.html — and I wonder if there is a hack to fake operator overload in comparison of objects?

jsguff
  • 105
  • 1
  • 5

2 Answers2

5

It really depends on what they mean by "How to make comparison a == b to be true?"

If you're allowed to change the constructor, then you could make your constructor a singleton:

function F(){
    if (!F.instance) {
        F.instance = this;
    } else {
        return F.instance;
    }
};
var a = new F();
var b = new F();
if (a === b) {
    //they are the same
}

If they want you to keep everything as it is but have a comparision that contains a == b then you could write the following:

if ("" + a == b) {
}

If they want to know methods of determine whether the two objects are instances of the same constructor function, then you could compare the constructor property or the __proto__ property:

if (a.constructor === b.constructor) {
}

if (a.__proto__ === b.__proto__) {
}

If they want to know methods of dermine whether these two objects have the same properties, you can either compare their JSON string:

if (JSON.stringify(a) === JSON.stringify(b)) {
}

or you write a function that recursively compares all the properties in both objects (deep comparision).

And the most simple answer to the question "How to make comparison a == b to be true?":

var a = new F();
var b = new F();

b = a;

if (a === b) {
    //surprise!!!
}
basilikum
  • 10,378
  • 5
  • 45
  • 58
0

my best answer would be this since you can compare different functions:

console.log(a.constructor+"" === b.constructor+"");

as it returns the functions as strings and then compare them literally .

example test:

function f1(){}
function f2(){}
var a = new f1(),
    b= new f2();
console.log(a.constructor+"" === b.constructor+"");
b = new f1();
console.log(a.constructor+"" === b.constructor+"");

DEMO

note: the === sign is not needed as the third would be for type comparison and both are strings at that point so using == would do exactly the same thing

EDIT: my actual answer to the question however would be: by removing new from the initialization

CME64
  • 1,673
  • 13
  • 24
  • We need **literally** `console.log(a == b) //=> true`. Not `.__proto__`, nor `.constructor`, nor `JSON.stringify(any)` – jsguff Jun 30 '13 at 12:32
  • @jsguff in that case, do you think you should add `a = a.constructor+""; b=..` before `console.log(a==b);` to keep the condition literally ? – CME64 Jun 30 '13 at 12:34
  • huh, why not `a = 42; b = 42` ? :) I think they (authors of test) mean exactly the `singleton` pattern, because it's the only way to make literally equal comparison `a == b` to be `true`. – jsguff Jun 30 '13 at 12:39
  • @jsguff ok then do you mind telling me the constraints of the question? because I don't see you have a chance doing anything to change a= false to true by just looking at it! – CME64 Jun 30 '13 at 12:43
  • I posted original question (word for word). There weren't any other details. – jsguff Jun 30 '13 at 12:49
  • @jsguff then you got my answer in the edit :) – CME64 Jun 30 '13 at 12:49
  • Your suggestion in edit changes sense of provided construction. Hope authors mean that we have exactly two instances of `F`. Maybe there is another right answer on this question (in case if we can't change constructor): **in no way** :) – jsguff Jun 30 '13 at 13:00