Opérateurs ternaires en JavaScript sans «autre»


149

J'ai toujours dû mettre nulldans les autres conditions qui n'ont rien. Y a-t-il quelque chose autour? Par exemple

condition ? x = true : null;

en gros, y a-t-il un moyen de faire:

condition ? x = true;

Maintenant, il apparaît comme une erreur de syntaxe

Pour info, voici un vrai exemple de code:

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null;

21
l'utilisation d'un ternaire comme condition ? x = true : null;devrait probablement s'écrire x = (condition ? true : null);. En nullpassant , en javascript est évalué à faux, donc dans CE cas, vous pouvez x = (condition);et obtenir le même résultat.
Matt S

1
matt, ta réponse est la meilleure, mais ce n'est pas une réponse, c'est un commentaire!
Cheeso

Matt, mon code ACTUEL est:! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null; une façon plus courte et meilleure d'écrire cela?
Oscar Godson

2
defaults.slideshowWidth = defaults.slideshowWidth || obj.find ('img'). width () + 'px';
kennebec

il serait préférable d'éviter l'attribution d'identité, donc cela devrait être une condition:if (!defaults.slideshowWidth) defaults.slideshowWidth = obj.find('img').width()+'px'
Mihail Malostanidis

Réponses:


226

Tout d'abord, une expression ternaire ne remplace pas une construction if / else - c'est un équivalent à une construction if / else qui renvoie une valeur. Autrement dit, une clause if / else est du code, une expression ternaire est une expression , ce qui signifie qu'elle renvoie une valeur.

Cela signifie plusieurs choses:

  • utilisez des expressions ternaires uniquement lorsque vous avez une variable sur le côté gauche de la =valeur de retour
  • utiliser uniquement des expressions ternaires lorsque la valeur renvoyée doit être l'une des deux valeurs (ou utiliser des expressions imbriquées si cela convient)
  • chaque partie de l'expression (après? et après:) doit renvoyer une valeur sans effets secondaires (l'expression x = truerenvoie true car toutes les expressions renvoient la dernière valeur, mais change également x sans que x n'ait d'effet sur la valeur renvoyée)

En bref - l'utilisation `` correcte '' d'une expression ternaire est

var resultofexpression = conditionasboolean ? truepart: falsepart;

Au lieu de votre exemple condition ? x=true : null ;, où vous utilisez une expression ternaire pour définir la valeur de x, vous pouvez utiliser ceci:

 condition && (x = true);

Ceci est toujours une expression et peut donc ne pas passer la validation, donc une approche encore meilleure serait

 void(condition && x = true);

Le dernier passera la validation.

Mais là encore, si la valeur attendue est un booléen, utilisez simplement le résultat de l'expression de condition elle-même

var x = (condition); // var x = (foo == "bar");

MISE À JOUR En ce qui concerne votre échantillon, c'est probablement plus approprié:

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

4
brillant SO, ne permettant pas de corriger les i/elsefautes de frappe car ce n'est pas assez de caractères.
rosée du

1
void (condition && x = true) - cela a l'air génial mais semble
générer une

1
void (condition && (x = true)) // garde l'affectation séparée de la première valeur
diamondsea

4
Cependant, ce n'est pas intuitif à lire, en particulier pour les développeurs non habitués à ce style. Vous pouvez tout aussi facilement et plus lisiblement écrire ceci que: if (condition) {x = true; }
diamondsea

2
Pourriez-vous expliquer ce que vous entendez par «pourrait ne pas passer la validation»? Je ne comprends pas pourquoi on devrait encapsuler l'expression void(). Merci.
gilad mayani le

20

Non, il faut trois opérandes. C'est pourquoi on les appelle ternaires opérateurs .

Cependant, pour ce que vous avez comme exemple, vous pouvez faire ceci:

if(condition) x = true;

Bien qu'il soit plus sûr d'avoir des accolades si vous devez ajouter plus d'une instruction à l'avenir:

if(condition) { x = true; }

Edit: Maintenant que vous mentionnez le code réel dans lequel votre question s'applique à:

if(!defaults.slideshowWidth)
    { defaults.slideshowWidth = obj.find('img').width()+'px'; }

1
Vous pouvez, mais vous ne devriez pas. Au moins pas sans accolades autour de lui - il est très sujet aux erreurs.
Konerak

1
Est-ce vrai? J'ai compris que la raison principale pour laquelle les boucles sont exigées est qu'elles facilitent la vie de jslint.
Cheeso

@Cheeso est sujet aux erreurs dans le sens de la refactorisation. Vous revenez pour ajouter plus de choses à faire dans le cas d'une vraie condition sans vous rendre compte qu'il n'y a pas d'accolades ici. Le nouveau code s'exécutera toujours plutôt que le cas de quand true.
Matt S

Non je sais, j'aime juste écrire des conditionnelles sans extras comme if () {} else {} quand son égal à simplement?:;
Oscar Godson

3
Honnêtement, je n'ai jamais connu de développeurs plus effrayés d'utiliser un langage que Javascript: -PI n'aimerait pas que quelqu'un me dise que je ne devrais pas utiliser d'accolades. Je les omette beaucoup et je n'ai jamais plus de problèmes que je manquerais accidentellement une attelle.
Andy E

12

Le plus souvent, les gens utilisent des opérateurs logiques pour raccourcir la syntaxe de l'instruction:

!defaults.slideshowWidth &&
  (defaults.slideshowWidth = obj.find('img').width()+'px');

Mais dans votre cas particulier, la syntaxe peut être encore plus simple

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

Ce code renverra la defaults.slideshowWidthvaleur si le defaults.slideshowWidthest évalué à vrai et la obj.find('img').width()+'px'valeur dans le cas contraire.

Voir l' évaluation de court-circuit des opérateurs logiques pour plus de détails.


11
var x = condition || null;

2
(defaults.slideshowWidth) || (defaults.slideshowWidth = obj.find('img').width()+'px')oudefaults.slideshowWidth = defaults.slideshowWidth || (obj.find('img').width()+'px')
Casey Chu

> Renvoie expr1 s'il peut être converti en vrai; sinon, renvoie expr2. Opérateurs logiques (MDN)
Szabolcs Páll

5

Tu pourrais écrire

x = condition ? true : x;

Ainsi, x n'est pas modifié lorsque la condition est fausse.

Ceci est alors équivalent à

if (condition) x = true

ÉDITER:

!defaults.slideshowWidth 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : null 

Il existe quelques alternatives - je ne dis pas que ce sont meilleures / pires - simplement des alternatives

La transmission de null comme troisième paramètre fonctionne car la valeur existante est nulle. Si vous refactorisez et modifiez la condition, il y a un risque que ce ne soit plus vrai. Passer la valeur existante comme 2ème choix dans les gardes ternaires contre ceci:

!defaults.slideshowWidth = 
      ? defaults.slideshowWidth = obj.find('img').width()+'px' 
      : defaults.slideshowwidth 

Plus sûr, mais peut-être pas aussi agréable à regarder, et plus de frappe. En pratique, j'écrirais probablement

defaults.slideshowWidth = defaults.slideshowWidth 
               || obj.find('img').width()+'px'

Un certain code en direct est (de toute façon pour se débarrasser de la valeur null dans ceci?):! Defaults.slideshowWidth? defaults.slideshowWidth = obj.find ('img'). width () + 'px': null;
Oscar Godson

2

Dans votre cas, je vois l'opérateur ternaire comme redondant. Vous pouvez affecter la variable directement à l'expression, en utilisant les opérateurs ||, &&.

!defaults.slideshowWidth ? defaults.slideshowWidth = obj.find('img').width()+'px' : null ;

va devenir :

defaults.slideshowWidth = defaults.slideshowWidth || obj.find('img').width()+'px';

C'est plus clair, c'est plus du style "javascript".


2

Qu'en est-il simplement

    if (condition) { code if condition = true };

1

Pour utiliser un opérateur ternaire sans autre à l'intérieur d'un tableau ou d'une déclaration d'objet, vous pouvez utiliser l'opérateur de propagation ES6 ...()

const cond = false;
const arr = [
  ...(cond ? ['a'] : []),
  'b',
];
    // ['b']

Et pour les objets:

const cond = false;
const obj = {
  ...(cond ? {a: 1} : {}),
  b: 2,
};
    // {b: 2}

source primaire

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.