5

Oto jedno z pytań w JavaScript internetowym test przed kwalifikacyjnej:Jak sprawić, aby porównanie obiektów `a == b` było prawdziwe?

function F(){}; 

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

Q: Jak zrobić porównanie a == b być true? (Np console.log(a == b) // true)

I odpowiedziało, że jest to niemożliwe, ponieważ a i b dwa różne przypadki F i równe porównanie w JS w przypadku braku pierwotnych porównuje wartość zadaną.

Ale jakiś czas temu przeczytałem artykuł "Fake operator przeciążający w JavaScript" autorstwa Axela Rauschmayera: http://www.2ality.com/2011/12/fake-operator-overloading.html - i zastanawiam się, czy jest hack do fałszywego przeciążenia operatora w porównaniu z obiektami?

+4

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

+0

@roasted, właściwie nie. W temacie, o którym wspomniałeś, odpowiedź polega na tym, jak dokonać właściwego porównania obiektów. Oto kolejny przypadek. – jsguff

+0

@jsguff przepraszam, po prostu przeczytałem tytuł i doszedłem do pochopnego wniosku –

Odpowiedz

5

To naprawdę zależy od tego, co rozumieją przez "Jak dokonać porównania a == b, aby było prawdziwe?"

Jeśli wolno zmieniać konstruktora, a następnie można dokonać konstruktor pojedyncza:

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 
} 

Jeśli chcą Państwo, aby wszystko jak jest, ale mają one blado, który zawiera a == b następnie można pisać, co następuje:

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

Jeśli chcą poznać metody ustalenia, czy dwa obiekty są instancjami tej samej funkcji konstruktora, a następnie można porównać właściwości constructor lub __proto__ nieruchomości:

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

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

Jeśli chcą poznać metody dermine czy te dwa obiekty mają te same właściwości, można też porównać ich JSON ciąg:

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

lub napisać funkcję, która rekursywnie porównuje wszystkie właściwości w obu obiektach (dokładne porównanie).

A najbardziej prosta odpowiedź na pytanie „Jak zrobić porównania, == b, aby mogło być prawdziwe?”:

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

b = a; 

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

' a === b' podaje fałsz! inne działają dobrze – CME64

+0

@ CME64 działa dobrze dla mnie: http://jsfiddle.net/hL3fA/ – basilikum

+0

dziwne, co się dzieje ?, sprawdź to: http://jsbin.com/okinob/3/edit – CME64

0

moją najlepszą odpowiedzią byłoby to, ponieważ można porównać różne funkcje:

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

ponieważ zwraca funkcje jako ciągi, a następnie porównać je dosłownie.

przykład testu:

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

uwaga: znak === nie jest potrzebna jako trzecia byłaby dla porównania typu i oba są struny w tym momencie tak wykorzystujące == zrobi dokładnie to samo, co

EDYCJA: moja rzeczywista odpowiedź na pytanie jednak wo uld być: usuwając nowy z inicjalizacji

+0

Potrzebujemy ** dosłownie ** 'console.log (a == b) // => true'. Nie '.__ proto__', ani' .constructor', ani 'JSON.stringify (any)' – jsguff

+0

@jsguff w takim przypadku, czy uważasz, że powinieneś dodać 'a = a.constructor +" "; b = .. 'przed' console.log (a == b); 'utrzymać dosłownie warunek? – CME64

+0

huh, dlaczego nie 'a = 42; b = 42'? :) Myślę, że oni (autorzy testu) mają dokładnie taki wzór 'singleton', ponieważ jest to jedyny sposób, aby dokonać dosłownie równego porównania' a == b' by być "true". – jsguff

Powiązane problemy