2015-07-24 16 views
27

Il C# 6.0 è appena stato rilasciato e presenta una nuova funzionalità molto carina che vorrei davvero utilizzare in JavaScript. Si chiamano Null-conditional operators. Questi usano una sintassi ?. o ?[].Operatori condizionali nulli

Ciò che è essenzialmente necessario consente di verificare che l'oggetto che si ottiene non sia null, prima di tentare di accedere a una proprietà. Se l'oggetto è null, otterrai il null come risultato dell'accesso alla tua proprietà.

int? length = customers?.Length; 

Così qui int può essere nullo, e che avrà valore se customers è nullo. Ciò che è ancora migliore è che è possibile concatenare questi:

int? length = customers?.orders?.Length; 

Non credo che possiamo farlo in JavaScript, ma mi chiedo qual è il modo più grazioso di fare qualcosa di simile. In generale trovo il concatenamento if blocchi di difficile lettura:

var length = null; 
if(customers && customers.orders) { 
    length = customers.orders.length; 
} 
+9

Riscriviamo alcuni motori JavaScript! – JNYRanger

+1

Correlato: http://stackoverflow.com/questions/476436/is-there-a-null-coalescing-operator-in-javascript – poke

+4

Si potrebbe 'var length = customers && customers.orders && customers.orders.length'; – xanatos

risposta

5

Chiamato "concatenamento opzionale", è attualmente una proposta TC39 in Stage 1. A Babel plugin tuttavia è già disponibile in v7. utilizzo

Esempio:

const obj = { 
    foo: { 
    bar: { 
     baz: 42, 
    }, 
    }, 
}; 

const baz = obj?.foo?.bar?.baz; // 42 

const safe = obj?.qux?.baz; // undefined 
+0

Grazie per aver condiviso quel Brent - è fantastico! – Ian

10

Js operatori logici non restituiscono true o false, ma truly o falsy valore stesso. Ad esempio nell'espressione x && y, se x è falsy, verrà restituito, altrimenti verrà restituito . Quindi la tabella di verità per l'operatore è corretta.

Nel tuo caso è possibile utilizzare l'espressione customers && customers.orders && customers.orders.Length per ottenere il valore length o il primo falsy uno.

Inoltre è possibile fare un po 'di magia, come ((customers || {}).orders || {}).length (Personalmente, non mi piace la sintassi e la possibile pressione raccolta dei rifiuti così)

o anche utilizzare maybe monade.

function Option(value) { 
    this.value = value; 
    this.hasValue = !!value; 
} 

Option.prototype.map = function(s) { 
    return this.hasValue 
     ? new Option(this.value[s]) 
     : this; 
} 

Option.prototype.valueOrNull = function() { 
    return this.hasValue ? this.value : null; 
} 

var length = 
    new Option(customers) 
     .map("orders") 
     .map("length") 
     .valueOrNull(); 

è più lungo di tutti gli approcci precedenti, ma mostra chiaramente le vostre intenzioni, senza alcuna magia dietro.

+0

Grazie - Potrei, ma cosa sono Mi piace provare e fare è arrivare a qualcosa che è molto meno prolisso. – Ian

+0

@Ian, forse, c'è una smth in quella lunga lista [(https://github.com/jashkenas/coffeescript/wiki/list-of-languages-that-compile-to-JS) con 'null-coalesce 'Operatore e js retrocompatibilità. Speravo in script di tipo, ma non c'è ancora il supporto. il copione del caffè ha 'elvis-operator', ma la sua sintassi e paradigma è troppo diverso da js. – Vladislav

+0

@Ian, ho aggiunto un'altra opzione nella mia risposta. – Vladislav