2016-06-23 15 views
21

Ho creato due nuovi oggetti:Confrontando un nuovo Object() con un altro new Object() in JavaScript

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

e dopo il confronto, ho ottenuto questi risultati:

var a = new Object(); 
 
var b = new Object(); 
 
console.log(a == b); //false 
 
console.log(a > b); //false 
 
console.log(b > a); //false 
 
console.log(a >= b); //true 
 
console.log(b >= a); //true

Per favore, spiegate come succede? riferimenti

+0

IIRC, oggetti sono memorizzati per riferimento, quindi è fondamentalmente guardando l'indirizzo dell'oggetto in memoria. –

+7

@JeremyJackson: No, non lo è. –

+2

I confronti di disuguaglianza che stai facendo stanno confrontando la stringa '[oggetto oggetto]' con se stessa, poiché tali confronti costringono gli operandi a una stringa in questo caso. Quelle stringhe non sono più grandi o meno l'una rispetto all'altra, ma sono maggiori o uguali o uguali o inferiori o uguali a. –

risposta

44

oggetto rispetto == o != (o === o !==) vengono confrontati in base a se si riferiscono allo stesso oggetto . Se è così, sono uguali; se no, non sono uguali.

Ma gli operatori di confronto relazionali (>, <, >=, e <=) non confrontare i riferimenti, che costringono gli operandi in qualcosa che possono confrontare: i numeri o stringhe.

Nel caso di new Object(), che la coercizione finisce per creare una stringa : "[object Object]". E, naturalmente, "[object Object]" >= "[object Object]" è vero perché sono uguali.

Così in effetti, cosa si sta effettivamente facendo è:

console.log(a == b);     //false 
console.log(String(a) > String(b)); //false 
console.log(String(b) > String(a)); //false 
console.log(String(a) >= String(b)); //true 
console.log(String(b) >= String(a)); //true 

... ma nota che altri tipi di oggetti costringono in modo diverso, perché gli oggetti possono scegliere il modo in cui costringono in questa situazione (in cui la specifica preferisce un numero su una stringa) implementando/sovrascrivendo valueOf. Ad esempio, gli oggetti Date costringono a un numero quando si applica un operatore relazionale a loro se l'altro operando può anche costringere al numero. Così si può utilizzare in modo affidabile dt1 > dt2 per vedere se dt1 rappresenta una data/ora dopo dt2   — ma può non uso dt1 == dt2 per controllare se dt1 e dt2 (due separati Date oggetti) hanno la stessa data/ora in loro, perché == controllerà per vedere se sono lo stesso oggetto invece. Il che ci porta a questo po 'di divertimento:

var dt1 = new Date(2016, 5, 23); 
 
var dt2 = new Date(2016, 5, 23); 
 
console.log(dt1 < dt2); // false 
 
console.log(dt1 > dt2); // false 
 
console.log(dt1 == dt2); // false!

Tutti i dettagli scabrosi possono essere trovati nella specifica:

+2

Sono davvero curioso di sapere cosa sta succedendo lì ... ora è chiaro :) –

+0

rtfm, ho ragione? –

+0

@PatrickRoberts: LOL non è inteso in quel modo, no, ma capisco cosa intendi. :-) –

6

Il comportamento è interamente come definito nella ECMAScript standards.

  1. a == b è false perché non si riferiscono allo stesso oggetto, come definito nella the Abstract Equality Comparison section:

    1. Se tipo (x) è la stessa Digitare (y), quindi

      a. Restituisce il risultato dell'esecuzione del Confronto di uguaglianza rigorosa x === y.

    The Strict Equality Comparison algorithm determini esso stesso, dopo che tutti gli altri tipi sono stati controllati:

    1. Se xey sono lo stesso valore oggetto, restituisce vero.
    2. Ritorno falso.
  2. a < b è false perché the abstract relational comparison algorithm converte l'operandi tipi non oggetto tramite il ToPrimitive abstract operation (che nel caso di oggetti risultati in una rappresentazione di stringa di "[object Object]").

    Poiché entrambi gli operandi verranno convertiti nello stesso valore di stringa, saranno uguali tra loro.

  3. a <= b è true perché b < a è false, come per la vecchia definizione di the Less-than-or-equal Operator (<=).

    1. Sia r il risultato di eseguire il confronto astratto relazionale rval < lval con LeftFirst uguale a false. (vedi 11.8.5).
    2. Se r è vero o indefinito, restituisce falso. Altrimenti, restituisce true.

    Nuovamente, l'operazione di confronto relazionale astratto convertirà operandi in stringa rappresentazioni "[object Object]" che saranno uguali tra di loro, in modo che il confronto b < a valuterà a false:

+1

2 è sbagliato. 'r' è solo' indefinito' se uno dei valori è 'NaN' che non è il caso qui (entrambi vengono convertiti in stringhe per http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.8). –

+0

Cosa ne pensi? Sia Let il risultato di chiamare ToPrimitive (x, hint Number) .' Questo converte 'x' in un numero o in una stringa.In caso di oggetti" plain "wit sarà una stringa perché' valueOf' non restituisce una primitiva (vedi link nel mio commento precedente) –

+1

@Thriggle: Guardate cosa fa ['ToPrimitive'] (http://www.ecma-international.org/ecma-262/5.1/#sec-9.1), quindi guardate all'inizio del Passo 3: *" Se non lo è il caso che sia 'Type (px)' sia 'String' e 'Type (py)' è 'String', quindi ..." * 'ToPrimitive (new Object())' restituisce una stringa. (Questi collegamenti sono conformi alla specifica 5.1, ma è ovviamente obsoleto. Più facile da leggere, ma obsoleto :-)) –

Problemi correlati