Exemplu de operator ternar JavaScript cu funcții (Programare, Javascript, Jquery)

Evik James a intrebat.
a intrebat.

Eu folosesc jQuery 1.7.1

Tocmai am început să folosesc operatorul ternar JavaScript pentru a înlocui declarațiile simple if/else. Am făcut acest lucru cu succes în mai multe locuri. Am fost surprins când am reușit cu succes să fac să funcționeze altceva când credeam cu siguranță că nu va funcționa, dar am încercat oricum.

Iată declarația originală:

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

Iată aceeași funcție folosind operatorul ternar:

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

Am fost surprins pentru că toate exemplele pe care le-am văzut folosite nu făceau decât să seteze variabilele astfel:

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

Întrebarea mea este dacă aceasta este o utilizare „normală” și dacă va funcționa în majoritatea versiunilor de JavaScript? Unde va da greș? Există și alte utilizări mai puțin evidente pentru el?

UPDATE — Mulțumesc pentru sfaturile din „lumea reală”!!!

Folosesc acest lucru ca funcție a mea:

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

Comentarii

  • Este normal și va funcționa foarte bine… În general, lizibilitatea este dificilă atunci când se folosesc operatori ternari, dar în cazul tău arată foarte bine. –  > Por Selvakumar Arumugam.
  • Hmm…. ați putea face și acest lucru, deoarece ambele acceptă aceleași argumente (IsChecked ? removeItem : addItem)($this). Cu toate acestea, pentru a răspunde la întrebarea dvs., da, acest lucru este normal și nu este nimic greșit în utilizarea operatorilor ternari, atâta timp cât aceștia nu afectează mentenabilitatea sau lizibilitatea într-o situație în care este necesar acest lucru. jsfiddle.net/vsB3f –  > Por Kevin B.
  • if($this.hasClass("IsChecked")) removeItem($this); else addItem($this) este modul corect. Operatorul ternar nu este menit pentru astfel de cazuri, ci pentru lucruri precum foo(isChecked ? 'bar' : meow()); (adică atunci când vă pasă de „valoarea de întoarcere” a ceea ce faceți în blocurile then/else) –  > Por ThiefMaster.
  • În exemplul tău, sări peste prima linie în favoarea acestui lucru: $(this).hasClass("IsChecked") ? removeItem($this) : addItem($this); Pot să înțeleg codul dvs. ca atare pe o singură linie, așa că se potrivește cu regula mea de bază (a se vedea mesajul de mai jos). Funcționează pentru mine. –  > Por Surreal Dreams.
  • Posibil duplicat al utilizării operatorului ternar în javascript pentru a invoca două funcții? –  > Por Cees Timmerman.
6 răspunsuri
JonnyReeves

Heh, există câteva utilizări destul de interesante ale sintaxei ternare în întrebarea dvs.; îmi place cel mai mult ultima…

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

Utilizarea ternarului aici este total inutilă – ați putea scrie pur și simplu

x = (1 < 2);

De asemenea, elementul de condiție al unei instrucțiuni ternare este întotdeauna evaluat ca o valoare booleană și, prin urmare, puteți exprima:

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

Pur și simplu ca:

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

De fapt, eu aș elimina și elementul IsChecked temporară, ceea ce vă lasă cu:

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

În ceea ce privește dacă aceasta este o sintaxă acceptabilă, cu siguranță că este! Este o modalitate excelentă de a reduce patru linii de cod la una singură fără a afecta lizibilitatea. Singurul sfat pe care vi l-aș da este să evitați să cuibăriți mai multe instrucțiuni ternare pe aceeași linie (pe această cale se află nebunia!)

Comentarii

  • rețineți că este posibil să doriți să evitați utilizarea majusculelor în numele claselor (IsChecked devenind is-checked) stackoverflow.com/questions/1547986/… –  > Por Adrien Be.
  • JS are funcții de primă clasă: ($this.hasClass("isChecked") ? removeItem : addItem)($this) –  > Por ClojureMostly.
Vise suprarealiste

Stilul ternar este folosit în general pentru a economisi spațiu. Din punct de vedere semantic, ele sunt identice. Eu prefer să folosesc sintaxa completă if/then/else pentru că nu-mi place să sacrific lizibilitatea – sunt de modă veche și îmi prefer parantezele.

Formatul complet if/then/else este folosit pentru aproape orice. Este deosebit de popular dacă intrați în blocuri mai mari de cod în fiecare ramură, dacă aveți un arbore if/else cu mai multe ramuri sau mai multe else/ifs într-un șir lung.

Operatorul ternar este obișnuit atunci când atribuiți o valoare unei variabile în funcție de o condiție simplă sau când luați mai multe decizii cu rezultate foarte scurte. Exemplul pe care îl citați nu are de fapt niciun sens, deoarece expresia va fi evaluată la una dintre cele două valori fără nicio logică suplimentară.

Idei bune:

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
{
    ...

Mai puțin bune:

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;
}

A foarte simplă regulă de bază – puteți înțelege totul la fel de bine sau mai bine pe o singură linie? Ternarul este OK. În caz contrar, extindeți-l.

Bartłomiej Zalewski

Aș vrea să adaug și eu ceva din partea mea.

O altă sintaxă posibilă pentru a apela funcții cu operatorul ternar, ar fi:

(condition ? fn1 : fn2)();

Poate fi utilă dacă trebuie să treceți aceeași listă de parametri la ambele funcții, astfel încât să trebuiască să le scrieți o singură dată.

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

Puteți utiliza operatorul ternar chiar și în cazul numelor funcțiilor membre, ceea ce mie personal îmi place foarte mult pentru a economisi spațiu:

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

sau

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

Un alt exemplu:

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

Jeff B

Nu este nimic deosebit de complicat în exemplul pe care l-ați postat.

Într-un operator ternar, primul argument (condiționalul) este evaluat, iar dacă rezultatul este true, al doilea argument este evaluat și returnat, în caz contrar, al treilea este evaluat și returnat. Fiecare dintre aceste argumente poate fi orice bloc de cod valid, inclusiv apeluri de funcții.

Gândiți-vă în felul următor:

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

Ar putea fi, de asemenea, scris ca::

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

Acest lucru este perfect valabil, iar aceste funcții pot conține orice cod arbitrar, indiferent dacă este legat de returnarea unei valori sau nu. În plus, rezultatele operației ternare nu trebuie să fie atribuite la nimic, la fel cum nici rezultatele funcțiilor nu trebuie să fie atribuite la nimic:

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

Acum, înlocuiți-le pur și simplu cu orice funcții arbitrare și veți obține ceva asemănător cu exemplul dumneavoastră:

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

Ultimul exemplu nu are nevoie deloc de un ternar, deoarece poate fi scris astfel:

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

Sam W

Dacă aveți de gând să aninați operatori ternari, cred că ar trebui să faceți ceva de genul acesta:

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

Este mult mai eficient de scris/citit decât:

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

La fel ca în cazul oricărei programări bune, spațiile albe fac ca totul să fie plăcut pentru cei care trebuie să citească codul după ce ați terminat proiectul.

Comentarii

  • Nu sunt deloc de acord cu comentariul dvs. de mai sus despre ternarul imbricate fiind mai ușor de citit și de depanat. Personal, aș prefera să văd blocul imbricate else/if înlocuit fie cu un bloc tabel de căutare fie o declarație switch. –  > Por JonnyReeves.
  • @JonnyReeves a fost de acord – de obicei, sintaxa ternară imbricata este cel mai bine utilizată atunci când se verifică condiții diferite (de ex. modulo de numere) –  > Por AlexFoxGill.
Himanshu Tiwari

Știu că întrebarea a primit deja un răspuns.

Dar permiteți-mi să adaug un punct aici. Acesta nu este doar cazul de adevărat sau fals. Vedeți mai jos:

var val="Do";

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

Aici, dacă val este Do sau Done, atunci c va fi 7, altfel va fi zero. În acest caz, c va fi 7.

Aceasta este de fapt o altă perspectivă a acestui operator.