Opérateur priorité avec Javascript opérateur ternaire
Je n'arrive pas à enrouler 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.
alors ma question Est Comment dois-je interpréter ce code correctement?
7 réponses
h.className = h.className + (h.className ? ' error' : 'error')
vous voulez que l'opérateur travaille pour h.className
, mieux vaut être précis à ce sujet.
Bien sûr, aucun mal ne devrait venir de h.className += ' error'
, mais c'est une autre question.
en outre, notez que +
a priorité sur l'opérateur ternaire: priorité de L'opérateur JavaScript
Pensez-y de cette façon:
<variable> = <expression> ? <true clause> : <false clause>
la façon dont la déclaration est exécutée est essentiellement comme suit:
- Ne
<expression>
true ou false? - si
<expression>
est évalué à true, alors la valeur de<true clause>
est assignée à<variable>
,<false clause>
est ignorée, et la déclaration suivante est exécutée. - si
<expression>
évalue à false, puis<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 cette langue et d'autres est que quel que soit le code dans <expression>
devrait produire un résultat booléen une fois évalué: soit vrai ou faux.
dans le cas de votre exemple, remplacer "attribué à" dans mon explication par "ajouté à", ou similaire pour n'importe quelle arithmétique vous êtes en utilisant, le cas échéant.
le +=
fait ce que vous voulez, mais dans la déclaration ternaire à la main droite de celui-ci, il vérifie si h.className
est falsey, ce qui serait si elle était indéterminée. Si c'est vrai (c.-à-d. si un nom de classe est déjà spécifié), alors l'erreur est ajoutée avec un espace (c.-à-d. en ajoutant une classe nouvelle ), sinon il est ajouté sans l'espace.
le code peut être réécrit comme vous le suggérez, mais vous devez spécifier que h.className
doit être utilisé pour la comparaison de la véracité, plutôt que pour l'utilisation de sa valeur réelle, dans l'opérateur ternaire, donc assurez-vous que vous ne vous embêtez pas avec la concaténation des valeurs en même temps que faire votre opération ternaire:
h.className = h.className + (h.className ? ' error' : 'error');
le côté droit de l'opérateur =
est évalué de gauche à droite. Donc,
g.className = h.className + h.className ? ' error' : 'error';`
est équivalent à
h.className = (h.className + h.className) ? ' error' : 'error';
pour être équivalent à
h.className += h.className ? ' error' : 'error';
il faut séparer le ternaire énoncé entre parenthèses
h.className = h.className + (h.className ? ' error' : 'error');
if (h.className) {
h.className = h.className + ' error';
} else {
h.className = h.className + 'error';
}
doit être l'équivalent de:
h.className += h.className ? ' error' : 'error';
je sais que c'est une question très ancienne, mais je ne suis pas 100% satisfait de l'une des réponses car elles semblent toutes incomplètes. Nous voici donc de nouveau de premiers principes:
l'objectif général de l'utilisateur:
résume le code: "je souhaite ajouter un nom de classe error
à une chaîne, éventuellement avec un espace principal s'il y a déjà des noms de classe dans la chaîne."
solution la plus simple
comme Kobi l'a souligné, il ya 5 ans, ayant un espace de tête dans les noms de classe ne sera pas causer de problèmes avec les navigateurs connus, de sorte que la solution correcte la plus courte serait en fait:
h.className += ' error';
Qui aurait été le la réponse à la problème .
quoi qu'il en soit, les questions posées étaient...
1) Pourquoi cela a-t-il fonctionné?
h.className += h.className ? ' error' : 'error'
l'opérateur conditionnel/ternaire fonctionne comme une instruction if, qui assigne le résultat de ses chemins true
ou false
à une variable.
de sorte que le code a fonctionné parce qu'il est évalué simplement comme:
if (h.className IS NOT null AND IS NOT undefined AND IS NOT '')
h.className += ' error'
else
h.className += 'error'
2) et pourquoi cette rupture?
h.className = h.className + h.className ? ' error' : 'error'
la question dit "qui donne une erreur dans ma console", qui peut induire en erreur vous pensez que le code ne fonctionne pas . En fait, le code suivant fonctionne, sans erreur , mais il renvoie "erreur" si la chaîne de caractères n'était pas "1519180920 vide" et "erreur" si la chaîne de caractères était vide et donc ne répond pas aux exigences .
ce code donne toujours une chaîne qui ne contient que ' error'
ou 'error'
parce qu'il évalue à ce pseudo code:
if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
h.className = ' error'
else
h.className = 'error'
la raison en est que l'opérateur d'addition ( +
au folk commun) a plus de" priorité " (6) que l'opérateur conditionnel/ternaire (15). je sais que les chiffres apparaissent à l'envers
priorité 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: Opérateur Javascript Priorité
Comment changer l'ordre d'évaluation:
maintenant que nous savons pourquoi il échoue, vous devez savoir comment le faire fonctionner.
D'autres réponses parlent de changer la priorité , mais vous ne pouvez pas . La préséance est liée à la langue. C'est juste un ensemble fixe de règles... Toutefois, vous pouvez modifier le ordre d'évaluation ...
l'outil dans notre boîte à outils qui peut changer l'ordre d'évaluation est l'opérateur de groupement (aka parenthèses). Il le fait en s'assurant que les expressions dans les parenthèses sont évaluées avant opérations en dehors des parenthèses. C'est tout ce qu'ils font, mais ça suffit.
Les crochetsfonctionnent simplement parce qu'ils opérateurs) ont priorité plus élevée que tous les autres opérateurs ("Il ya maintenant un niveau 0").
en ajoutant simplement des crochets vous modifiez l'ordre d'évaluation pour s'assurer que le test conditionnel est effectué en premier, avant la simple chaîne concaténation:
h.className = h.className + (h.className ? ' error' : 'error')
je vais maintenant laisser cette réponse rouiller invisible parmi les autres:)
j'aimerais choisir l'explication de wayne:
<variable> = <expression> ? <true clause> : <false clause>
permet de considérer les deux cas:
case 1:
h.className += h.className ? 'true' : 'false'
- opérateur d'affectation fonctionne très bien et la valeur est ajoutée
- lorsque pour la première fois, o/p: false,
- 2e fois. o/p: falsetrue -- valeurs maintient en ajoutant
case2: h.className = h.className + h.className ? 'true' : 'false'
- le résultat n'est pas le même que dans le cas 1
- lorsque pour la première fois, o/p: false,
- 2e fois. o/p: faux-valeurs ne tiennent pas en ajoutant
explanation
dans le code ci-dessus, l'affaire 1 fonctionne amende
attendu que case2:
h.className = h.className + h.className ? 'true' : 'false'
is executed as
h.className = (h.className + h.className) ? 'true' : 'false'
h.className + h.className
= > considéré comme l'expression de l'opérateur ternaire en tant qu'opérateur ternaire a priorité plus élevée. donc, toujours le résultat de l'expression ternaire est assigné
vous devez définir la priorité en utilisant les parenthèses
Vous devez définir l'ordre d'évaluation à considérer avec l'aide de crochets pour le cas 2 cas 1
h.className = h.className + (h.className ? ' error' : 'error')