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.