Je ne peux pas sembler envelopper ma tête autour de la première partie de ce code (+ =) en combinaison avec l'opérateur ternaire.
h.className += h.className ? ' error' : 'error'
La façon dont je pense que ce code fonctionne est la suivante:
h.className = h.className + h.className ? ' error' : 'error'
Mais ce n'est pas correct car cela donne une erreur dans ma console.
Ma question est donc de savoir comment dois-je interpréter ce code correctement?
javascript
variable-assignment
conditional-operator
operator-precedence
compound-assignment
Baijs
la source
la source
h.className += ' error'
, cela laisse également un espace vide au début de la chaîne si elle était initialement vide. Je crois que le but de l'opération ternaire est de produire une corde d'apparence propre.Pense-y de cette façon:
La façon dont l'instruction est exécutée est essentiellement la suivante:
<expression>
à vrai ou est-ce qu'il est faux?<expression>
la valeur<true clause>
est true, la valeur de est affectée à<variable>
,<false clause>
est ignorée et l'instruction suivante est exécutée.<expression>
false, alors<true clause>
est ignoré et la valeur de<false clause>
est attribuée à<variable>
.La chose importante à réaliser avec l'opérateur ternaire dans ce langage et dans d'autres est que quel que soit le code qui se trouve, il
<expression>
doit produire un résultat booléen lorsqu'il est évalué: vrai ou faux.Dans le cas de votre exemple, remplacez «assigné à» dans mon explication par «ajouté à», ou similaire pour l'arithmétique abrégée que vous utilisez, le cas échéant.
la source
+
a une plus grande priorité que l'opérateur conditionnel / ternaire (en fait, l'opérateur conditionnel est presque toujours le dernier) évalué dans n'importe quelle expression).Le
+=
fait ce que vous voulez, mais dans la déclaration ternaire à sa droite, il vérifie sih.className
est faux, ce qu'il serait s'il n'était pas défini. Si c'est vrai (c'est-à-dire si un nom de classe est déjà spécifié), alors l'erreur est ajoutée avec un espace (c'est-à-dire en ajoutant une nouvelle classe), sinon elle est ajoutée sans l'espace.Le code peut être réécrit comme vous le suggérez, mais vous devez spécifier qu'il
h.className
doit être utilisé pour la comparaison de vérité, plutôt que pour utiliser sa valeur réelle, dans l'opérateur ternaire, alors assurez-vous de ne pas vous soucier de la concaténation des valeurs en même temps que votre opération ternaire:la source
undefined
n'est-ce pas faux, c'est juste traité comme si c'étaitLe côté droit de l'
=
opérateur est évalué de gauche à droite. Alors,est équivalent à
Etre équivalent à
vous devez séparer l'énoncé ternaire entre parenthèses
la source
devrait être équivalent à:
la source
Je sais que c'est une question très ancienne, mais je ne suis satisfait à 100% d'aucune des réponses car elles semblent toutes incomplètes. Donc, nous revenons des premiers principes:
L'objectif général de l'utilisateur:
Résumant le code: "Je souhaite ajouter un
error
nom de classe à une chaîne, éventuellement avec un espace au début s'il y a déjà des noms de classe dans la chaîne."La solution la plus simple
Comme Kobi l'a souligné, il y a 5 ans, avoir un espace de premier plan dans les noms de classe ne posera aucun problème avec les navigateurs connus, donc la solution correcte la plus courte serait en fait:
Cela aurait dû être la vraie réponse au problème réel .
Quoi qu'il en soit, les questions posées étaient ...
1) Pourquoi cela a-t-il fonctionné?
L'opérateur conditionnel / ternaire fonctionne comme une instruction if, qui attribue le résultat de ses chemins
true
oufalse
à une variable.Donc, ce code a fonctionné car il est évalué simplement comme:
2) et pourquoi cette rupture?
La question indique "qui donne une erreur [n] dans ma console", ce qui peut vous induire en erreur en pensant que le code ne fonctionne pas . En fait, le code suivant s'exécute, sans erreur , mais il renvoie simplement «erreur» si la chaîne n'était pas vide et «erreur» si la chaîne était vide et ne répondait donc pas aux exigences .
Ce code aboutit toujours à une chaîne qui contient uniquement
' error'
ou'error'
parce qu'il évalue ce pseudo code:La raison en est que l'opérateur d'addition (
+
aux gens du commun) a une "priorité" plus élevée (6) que l'opérateur conditionnel / ternaire (15). Je sais que les chiffres apparaissent à l'enversLa préséance signifie simplement que chaque type d'opérateur dans une langue est évalué dans un ordre prédéfini particulier (et pas seulement de gauche à droite).
Référence: Javascript Operator Precedence
Comment changer l'ordre d'évaluation:
Maintenant que nous savons pourquoi cela échoue, vous devez savoir comment le faire fonctionner.
Certaines autres réponses parlent de changer la priorité , mais vous ne pouvez pas . La préséance est câblée dans la langue. Ce n'est qu'un ensemble fixe de règles ... Cependant, vous pouvez changer l' ordre d'évaluation ...
L'outil de notre boîte à outils qui peut changer l'ordre d'évaluation est l'opérateur de regroupement (aka parenthèses). Pour ce faire, il s'assure que les expressions entre crochets sont évaluées avant les opérations en dehors des crochets. C'est tout ce qu'ils font, mais c'est suffisant.
Les parenthèses fonctionnent simplement parce qu'elles (opérateurs de regroupement) ont une priorité plus élevée que tous les autres opérateurs ("il y a maintenant un niveau 0").
En ajoutant simplement des crochets, vous modifiez l'ordre d'évaluation pour vous assurer que le test conditionnel est effectué en premier, avant la simple concaténation de chaînes:
Je vais maintenant laisser cette réponse à la rouille invisible parmi les autres :)
la source
Je voudrais choisir l'explication de wayne:
Considérons les deux cas:
explanation
considérant que case2:
h.className + h.className
=> considéré comme une expression pour l'opérateur ternaire car l'opérateur ternaire a une priorité plus élevée. donc, toujours le résultat de l'expression ternaire est juste assignéVous devez définir la priorité en utilisant des crochetsVous devez définir l'ordre d'évaluation à prendre en compte à l'aide de parenthèses pour que le cas 2 fonctionne comme le cas 1
la source