Perché l'operatore && produrre il tipo del secondo operando

voti
24

La specifica dattiloscritto stati in §4.15.6 circa l' &&operatore:

L'operatore && permette gli operandi di essere di qualsiasi tipo e produce un risultato dello stesso tipo del secondo operando .

In Javascript, l' &&operatore restituisce il primo operando se è falsy, altrimenti restituisce il secondo operando ( vedi ECMA-262 §11.11 ).

Ciò significa che se l'operando di sinistra è falsy, &&restituirà un valore che corrisponde al tipo di operando sinistro. Per esempio,

typeof ( false && {}      ) === boolean // true
typeof ( ''    && 1       ) === string  // true
typeof ( null  && hello ) === object  // true
typeof ( NaN   && true    ) === number  // true

Carattere tipografico, secondo la regola sopra citata, sarebbe errato prevedere i tipi di espressioni di cui sopra siano Object, Number, Stringe Boolean, rispettivamente.

Mi sto perdendo qualcosa? C'è un buon motivo per fare il tipo di &&espressione corrisponde al tipo del secondo operando? Il tipo di risultato non dovrebbe comportarsi come l' ||operatore, e tornare il miglior tipo comune dei due operandi, e Anyse non v'è miglior tipo comune?

È pubblicato 02/10/2012 alle 16:50
fonte dall'utente
In altre lingue...                            


1 risposte

voti
20

Per farla breve, non c'è nessuna soluzione qui che piace a tutti.

Considerate questo idioma comune:

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

Sarebbe piuttosto inconsistente a rinunciare e decidere che 'indirizzo' è 'qualsiasi' perché non c'è miglior tipo comune tra il Cliente e Indirizzo.

Nella maggior parte dei casi in cui viene utilizzato l'operatore &&, sia i tipi già corrispondono o && viene utilizzato in maniera valore coalescenti come sopra. In entrambi i casi, il ritorno il tipo di l'operando di destra dà all'utente del tipo previsto.

Mentre la sicurezza tipo è tecnicamente abbattere, a questo punto, non è farlo in un modo che è suscettibile di provocare un errore. O si sta andando a testare il valore risultante per truthiness (nel qual caso il tipo è più o meno irrilevante), o avete intenzione di utilizzare l'operando presuntiva giusta per alcune operazioni (nell'esempio sopra fare entrambe).

Se guardiamo gli esempi che hai elencato e facciamo finta l'operando di sinistra è indeterminato truthy o falsy e quindi provare a scrivere il codice sano di mente che avrebbe operare sul valore di ritorno, diventa molto più chiaro - non c'è solo tanto si può fare con la 'false && {}' che non sia già in corso in una 'qualsiasi' posizione di discussione o di prova truthiness.


appendice

Dal momento che alcune persone non sono stati convinti da quanto sopra, ecco una spiegazione diversa.

Facciamo finta per un momento che il sistema di tipo dattiloscritto ha aggiunto tre nuovi tipi: Truthy<T>, Falsy<T>, e Maybe<T>, che rappresentano possibili valori truthy / falsy di tipo T. Le regole per questi tipi sono i seguenti:

  1. Truthy<T> si comporta esattamente come T
  2. Non è possibile accedere a qualsiasi proprietà di Falsy<T>
  3. Un'espressione del tipo Maybe<T>, se usati come la condizione in un ifblocco, diventa Truthy<T>nel corpo dello stesso ifblocco e Falsy<T>in elseblocco

Questo avrebbe permesso di fare le cose in questo modo:

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

Abbastanza bene finora. Ora siamo in grado di capire quali sono le regole di tipo sono per l'operatore &&.

  • Truthy<T> && x dovrebbe essere un errore - Se il lato sinistro è noto per essere truthy, si dovrebbe avere appena scritto x
  • Falsy<T> && xdovrebbe essere un errore - se il lato sinistro è noto per essere falsy, xè codice irraggiungibile
  • Maybe<T> && x dovrebbe produrre ... che cosa?

Sappiamo che il risultato di Maybe<T> && xsarà un valore falsy di tipo To x. Esso non può produrre Truthy<T>(a meno che T== il tipo di xnel qual caso questa intera discussione è discutibile). Chiamiamo questo nuovo tipo Falsy<T> XOR Maybe<U>.

Quali dovrebbero essere le regole di Falsy<T> XOR Maybe<U>essere?

  • Chiaramente, non è possibile utilizzare le proprietà di Tsu di esso. Se il valore è di tipo T, è falsy, e non sicuro per l'uso.
  • Si dovrebbe essere in grado di usarlo come Maybe<U>, dal momento che Falsy<T>e Falsy<U>hanno gli stessi comportamenti
  • Non si dovrebbe essere in grado di utilizzare le proprietà di U, perché il valore potrebbe essere ancora falsy.
  • Se lo si utilizza in una ifprova, allora dovrebbe diventare Truthy<U>nel blocco di quella ifdichiarazione

In altre parole, Falsy<T> XOR Maybe<U> è Maybe<U> . Segue tutte le stesse regole. Non è necessario complicare il sistema di tipo affatto qui aggiungendo questo strano XORtipo, perché un tipo che si adatta a tutte le specifiche è necessario esiste già.

Questo è un po 'come dare a qualcuno una scatola e dire "Questo è sia una scatola vuota di spazzatura, o di una scatola piena di materiali riciclabili". È possibile svuotare in modo sicuro il contenuto della scatola nel cestino.

Risposto il 02/10/2012 a 17:55
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more