5

Hier ist eine der Fragen in JavaScript Online-Test vor Vorstellungsgespräch:Wie macht man Vergleiche von Objekten `a == b`, um wahr zu sein?

function F(){}; 

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

Q: Wie Vergleich a == b zu machen true zu sein? (Z.B. console.log(a == b) // true)

I antwortete, dass es unmöglich ist, weil a und b sind zwei verschiedene Fälle von F und gleich Vergleich in JS im Fall der Nicht-Primitiven vergleicht Referenz.

Vor einiger Zeit habe ich den Artikel "Fake operator overloading in JavaScript" von Axel Rauschmayer gelesen: http://www.2ality.com/2011/12/fake-operator-overloading.html - und ich frage mich, ob es im Vergleich zu Objekten einen Hack zu gefälschter Operatorüberladung gibt?

+4

'JSON.stringify (a) == JSON.stringify (b)' –

+0

@roasted, eigentlich nicht zu entfernen. In dem Thema, das Sie erwähnt haben, geht es darum, Objekte auf die richtige Art und Weise zu vergleichen. Hier ist ein anderer Fall. – jsguff

+0

@jsguff Entschuldigung, nur gelesen Titel Ich kam zu einer voreiligen Schlussfolgerung –

Antwort

5

Es hängt wirklich davon ab, was sie mit "Wie mache ich Vergleich a == b, um wahr zu sein?"

Wenn Sie den Konstruktor ändern erlaubt sind, dann könnten Sie Ihren Konstruktor einen Singleton machen:

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 
} 

Wenn sie alles behalten wollen, wie es aber einen Vergleich ist, dass enthält a == b dann könnte man schreiben Sie die folgenden:

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

Wenn sie bestimmen, wissen, Methoden wollen, ob die beiden Objekte Instanzen derselben Konstruktorfunktion sind, dann könnten Sie die constructor Eigenschaft oder dievergleichenEigenschaft:

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

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

Wenn sie Methoden der Dermine wissen wollen, ob diese beiden Objekte die gleichen Eigenschaften haben, können Sie entweder ihre JSON-String vergleichen:

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

oder Sie eine Funktion schreiben, die rekursiv vergleicht alle Eigenschaften in beiden Objekten (tiefer Vergleich).

Und die einfachste Antwort auf die Frage „Wie Vergleich a == b machen wahr zu sein?“:

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

b = a; 

if (a === b) { 
    //surprise!!! 
} 
+0

' a === b' ergibt falsch! die anderen funktionieren gut – CME64

+0

@ CME64 funktioniert gut für mich: http://jsfiddle.net/hL3fA/ – basilikum

+0

seltsam, was ist los ?, überprüfen Sie dies: http://jsbin.com/okinob/3/edit – CME64

0

meine beste Antwort wäre dies, da Sie verschiedene Funktionen vergleichen:

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

wie es die Funktionen als Zeichenfolgen zurückgibt und sie dann wörtlich vergleicht.

Beispiel 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

Anmerkung: die === Zeichen nicht als dritte benötigt für Typ Vergleich wäre und beide sind Strings an diesem Punkt so == mit genau tun würde, die gleiche Sache

EDIT: meine eigentliche Antwort auf die Frage jedoch wo sein ULD: von neue von der Initialisierung

+0

Wir brauchen ** wörtlich ** 'console.log (a == b) // => true'. Nicht '.__ proto__', noch' .constructor', noch 'JSON.stringify (any)' – jsguff

+0

@jsguff in diesem Fall, denkst du, du solltest 'a = a.constructor +" "hinzufügen; b = .. 'vor' console.log (a == b); 'um den Zustand wörtlich zu halten? – CME64

+0

huh, warum nicht 'a = 42; b = 42? :) Ich denke, dass sie (Autoren des Tests) genau das "Singleton" -Muster meinen, weil es der einzige Weg ist, um einen wörtlichen Vergleich zu machen "a == b", um "wahr" zu sein. – jsguff