Esempio di operatore ternario JavaScript con funzioni


91

Sto usando jQuery 1.7.1

Sto appena iniziando a utilizzare l'operatore ternario JavaScript per sostituire semplici istruzioni if ​​/ else. L'ho fatto con successo in diversi posti. Sono rimasto sorpreso quando ho fatto funzionare con successo qualcos'altro quando pensavo che non sarebbe successo, ma ho provato comunque.

Ecco la dichiarazione originale:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    if (IsChecked == true){
        removeItem($this);
    } else {
        addItem($this);
    }
}

Ecco la stessa funzione usando l'operatore ternario:

function updateItem() {
    $this = $(this);
    var IsChecked = $this.hasClass("IsChecked");
    (IsChecked == true) ? removeItem($this) : addItem($this);
}

Sono rimasto sorpreso perché tutti gli esempi che ho visto utilizzati stavano semplicemente impostando variabili come questa:

x = (1 < 2) ? true : false;

La mia domanda è se questo è un uso "normale" e funzionerà nella maggior parte delle versioni di JavaScript? Dove fallirà? Ci sono altri usi meno ovvi per questo?

AGGIORNAMENTO - Grazie per il consiglio del "mondo reale" !!!

Lo sto usando come funzione:

function updateItem() {
    $this = $(this);
    $this.hasClass("IsChecked") ? removeItem($this) : addItem($this);
}

È normale e funzionerà benissimo .. In generale, la leggibilità è difficile quando si usano operatori ternari, ma nel tuo caso sembra a posto.
Selvakumar Arumugam

1
Hmm ... potresti anche farlo poiché entrambi accettano gli stessi argomenti (IsChecked ? removeItem : addItem)($this). Tuttavia, per rispondere alla tua domanda, sì, questo è normale e non c'è niente di sbagliato nell'usare operatori ternari purché non sminuiscano la manutenibilità o leggibilità in una situazione in cui è necessario. jsfiddle.net/vsB3f
Kevin B

if($this.hasClass("IsChecked")) removeItem($this); else addItem($this)è il modo corretto. L'operatore ternario non è inteso per casi come questo ma per cose come foo(isChecked ? 'bar' : meow());(cioè quando ti interessa il "valore di ritorno" di qualunque cosa tu faccia nei blocchi then / else)
ThiefMaster

1
Nel tuo esempio, salta la prima riga a favore di questo: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); posso capire il tuo codice così com'è su una riga, quindi si adatta alla mia regola pratica (vedi post sotto). Per me va bene.
Surreal Dreams

Risposte:


189

Eh, ci sono alcuni usi piuttosto eccitanti della sintassi ternaria nella tua domanda; L'ultima mi piace di più ...

x = (1 < 2) ? true : false;

L'uso del ternario qui è del tutto inconsistente: potresti semplicemente scrivere

x = (1 < 2);

Allo stesso modo, l'elemento condition di un'istruzione ternaria viene sempre valutato come valore booleano, quindi puoi esprimere:

(IsChecked == true) ? removeItem($this) : addItem($this);

Semplicemente come:

(IsChecked) ? removeItem($this) : addItem($this);

Infatti, rimuoverei anche il IsCheckedtemporaneo che ti lascia con:

($this.hasClass("IsChecked")) ? removeItem($this) : addItem($this);

Per quanto riguarda se questa è una sintassi accettabile, lo è sicuramente! È un ottimo modo per ridurre quattro righe di codice in una senza influire sulla leggibilità. L'unico consiglio che ti darei è di evitare di annidare più affermazioni ternarie sulla stessa riga (in questo modo giace la follia!)


nota che potresti voler evitare di usare le maiuscole nei nomi delle classi (IsChecked diventa is-check) stackoverflow.com/questions/1547986/…
Adrien Be

JS ha funzioni di prima classe:($this.hasClass("isChecked") ? removeItem : addItem)($this)
Clojure

22

Lo stile ternario viene generalmente utilizzato per risparmiare spazio. Semanticamente, sono identici. Preferisco seguire la sintassi completa if / then / else perché non mi piace sacrificare la leggibilità: sono della vecchia scuola e preferisco le mie parentesi graffe.

Il formato completo if / then / else viene utilizzato praticamente per tutto. È particolarmente popolare se entri in blocchi di codice più grandi in ogni ramo, hai un albero if / else con ramificazioni multiple o più else / if in una lunga stringa.

L'operatore ternario è comune quando si assegna un valore a una variabile in base a una condizione semplice o si prendono più decisioni con risultati molto brevi. L'esempio che citi in realtà non ha senso, perché l'espressione restituirà uno dei due valori senza alcuna logica aggiuntiva.

Buone idee:

this > that ? alert(this) : alert(that);  //nice and short, little loss of meaning

if(expression)  //longer blocks but organized and can be grasped by humans
{
    //35 lines of code here
}
else if (something_else)
{
    //40 more lines here
}
else if (another_one)  /etc, etc
{
    ...

Meno bene:

this > that ? testFucntion() ? thirdFunction() ? imlost() : whathappuh() : lostinsyntax() : thisisprobablybrokennow() ? //I'm lost in my own (awful) example by now.
//Not complete... or for average humans to read.

if(this != that)  //Ternary would be done by now
{
    x = this;
}
else
}
    x = this + 2;
}

Una regola pratica di base : puoi capire anche l'intera cosa o meglio su una riga? Il ternario va bene. Altrimenti espanderlo.


7

Non c'è niente di particolarmente complicato nell'esempio che hai pubblicato.

In un operatore ternario, viene valutato il primo argomento (il condizionale) e se il risultato è true, viene valutato e restituito il secondo argomento, altrimenti viene valutato e restituito il terzo. Ciascuno di questi argomenti può essere qualsiasi blocco di codice valido, comprese le chiamate di funzione.

Pensare in questo modo:

var x = (1 < 2) ? true : false;

Potrebbe anche essere scritto come:

var x = (1 < 2) ? getTrueValue() : getFalseValue();

Questo è perfettamente valido e quelle funzioni possono contenere qualsiasi codice arbitrario, che sia correlato alla restituzione di un valore o meno. Inoltre, i risultati dell'operazione ternaria non devono essere assegnati a nulla, così come i risultati delle funzioni non devono essere assegnati a nulla:

(1 < 2) ? getTrueValue() : getFalseValue();

Ora sostituisci semplicemente quelli con qualsiasi funzione arbitraria e ti rimane qualcosa come il tuo esempio:

(1 < 2) ? removeItem($this) : addItem($this);

Ora il tuo ultimo esempio non ha davvero bisogno di un ternario, poiché può essere scritto in questo modo:

x = (1 < 2);  // x will be set to "true"

6

Se hai intenzione di annidare operatori ternari, credo che vorresti fare qualcosa del genere:

   var audience = (countrycode == 'eu') ? 'audienceEU' :
                  (countrycode == 'jp') ? 'audienceJP' :
                  (countrycode == 'cn') ? 'audienceCN' :
                  'audienceUS';

È molto più efficiente scrivere / leggere rispetto a:

var audience = 'audienceUS';
if countrycode == 'eu' {
   audience = 'audienceEU';
} else if countrycode == 'jp' {
   audience = 'audienceJP';
} else if countrycode == 'cn' {
   audience = 'audienceCN';
}

Come con tutta la buona programmazione, gli spazi bianchi rendono tutto piacevole per le persone che devono leggere il tuo codice dopo aver finito con il progetto.


6
Completamente in disaccordo con il tuo commento sopra sul ternario annidato più facile da leggere e da correggere. Personalmente, preferirei vedere il blocco else / if nidificato sostituito con una tabella di ricerca o un'istruzione switch.
JonnyReeves

@JonnyReeves è d'accordo - di solito la sintassi ternaria annidata è meglio utilizzata quando si controllano condizioni diverse (ad esempio modulo di numeri )
AlexFoxGill

6

Vorrei anche aggiungere qualcosa da me.

Un'altra possibile sintassi per chiamare funzioni con l'operatore ternario, sarebbe:

(condition ? fn1 : fn2)();

Può essere utile se devi passare lo stesso elenco di parametri a entrambe le funzioni, quindi devi scriverli una sola volta.

(condition ? fn1 : fn2)(arg1, arg2, arg3, arg4, arg5);

Puoi usare l'operatore ternario anche con i nomi delle funzioni dei membri, che personalmente mi piace molto per risparmiare spazio:

$('.some-element')[showThisElement ? 'addClass' : 'removeClass']('visible');

o

$('.some-element')[(showThisElement ? 'add' : 'remove') + 'Class']('visible');

Un altro esempio:

var addToEnd = true; //or false
var list = [1,2,3,4];
list[addToEnd ? 'push' : 'unshift'](5);

2

So che la domanda ha già una risposta.

Ma lasciatemi aggiungere un punto qui. Questo non è solo il caso di vero o falso. Vedi sotto:

var val="Do";

Var c= (val == "Do" || val == "Done")
          ? 7
          : 0

Qui se val è Do o Done allora c sarà 7 altrimenti sarà zero. In questo caso c sarà 7.

Questa è in realtà un'altra prospettiva di questo operatore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.