Question

Je ne peux pas semble 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 comme suit:

h.className = h.className + h.className ? ' error' : 'error'

Mais ce n'est pas correct parce que cela donne une erreur dans ma console.

Alors, ma question est de savoir comment dois-je Interpet ce code correctement?

Était-ce utile?

La solution

h.className = h.className + (h.className ? ' error' : 'error')

Vous voulez que l'opérateur de travailler pour h.className, mieux être précis à ce sujet.
Bien sûr, aucun mal ne devrait provenir h.className += ' error', mais c'est une autre affaire.

Notez également que + a priorité sur l'opérateur ternaire: JavaScript opérateur précédence

Autres conseils

Pensez-y de cette façon:

<variable> = <expression> ? <true clause> : <false clause>

La façon dont la déclaration est exécuté est essentiellement comme suit:

  1. Est-ce que <expression> évaluer true, ou faut-il évaluer false?
  2. Si <expression> évalue à true, alors la valeur de <true clause> est affecté à <variable>, <false clause> est ignorée, et l'instruction suivante est exécutée.
  3. Si <expression> évalue à false, <true clause> est ignorée et la valeur de <false clause> est affecté à <variable>.

La chose importante à réaliser avec l'opérateur ternaire dans ce domaine et d'autres langues est que quel que soit le code est en <expression> devrait produire un résultat booléen lorsqu'il est évalué: true ou false

.

Dans le cas de votre exemple remplacer « attribué à » dans mon explication avec « ajouté à », ou similaire pour l'arithmétique selon un raccourci que vous utilisez, 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, qu'il serait si elle était définie. Si c'est truthy (à savoir si un nom de classe est déjà spécifié), puis l'erreur est ajouté avec un espace (par exemple l'ajout d'un nouveau classe), sinon il est ajouté sans l'espace.

Le code pourrait être réécrite comme vous le suggérez, mais vous devez préciser que h.className doit être utilisé pour truthiness de comparaison, plutôt que pour l'utilisation de sa valeur réelle, dans l'opérateur ternaire, alors assurez-vous ne vous préoccupez pas 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ée à gauche à droite. Ainsi,

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

vous devez séparer la déclaration ternaire 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';
}

devrait être équivalent:

h.className += h.className ? ' error' : 'error';

Je sais que c'est une question très ancienne, mais je ne suis pas satisfait à 100% avec l'une des réponses que tous semblent incomplètes. Alors on y va à nouveau de premiers principes:

objectif global de l'utilisateur:

Résumant le code: «Je veux ajouter un nom de classe error à une chaîne, éventuellement avec un espace de premier plan s'il y a des noms déjà classe dans la chaîne »

solution Simplest

Kobi a fait remarquer, il y a 5 ans, ayant un espace de premier plan dans les noms de classe ne causera aucun problème avec tous les navigateurs connus, donc la plus courte solution correcte serait en fait:

h.className += ' error';

Cela aurait dû être le réponse réelle problème réel .


Quoi qu'il en soit, les questions posées étaient ...

1) Pourquoi est-ce travail?

h.className += h.className ? ' error' : 'error'

L'opérateur conditionnel / ternaire fonctionne comme une instruction if, qui affecte le résultat de ses chemins de true ou false à une variable.

Alors que le code a fonctionné parce qu'il est évalué simplement:

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'

Les Etats question « qui donne un [n] erreur dans ma console », ce qui peut vous induire en erreur en pensant que le code ne fonctionne pas . En fait, le code suivant ne fonctionne, sans erreur , mais il retourne simplement « erreur » si la chaîne était pas vide et « erreur » si la chaîne était vide et ainsi ne répondaient pas aux exigences .

ce code entraîne 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 est que l'opérateur d'addition (+ au peuple commun) a « priorité » (6) supérieur à l'opérateur ternaire conditionnel / (15). Je sais les chiffres apparaissent en arrière

précédence signifie simplement que chaque type d'opérateur dans une langue est évaluée dans un ordre prédéfini particulier (et pas seulement de gauche à droite).

Référence: Javascript opérateur précédence

Comment faire pour modifier l'ordre d'évaluation:

Maintenant, 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 . Est précédence dur dans la langue. C'est juste un ensemble fixe de règles ... Cependant, vous pouvez modifier le ordre d'évaluation ...

L'outil dans notre boîte à outils qui peuvent modifier l'ordre d'évaluation est l'opérateur de regroupement (alias entre parenthèses). Elle le fait en assurant 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 crochets fonctionnent simplement parce qu'ils (les opérateurs de groupement) ont une priorité plus élevée que tous les autres opérateurs ( "il y a maintenant un niveau 0").

En ajoutant simplement entre parenthèses vous changer l'ordre d'évaluation pour assurer le test conditionnel est effectué en premier lieu, avant la concaténation de chaîne simple:

h.className = h.className + (h.className ? ' error' : 'error')

je quitte maintenant cette réponse à la rouille invisible parmi les autres:)

Je voudrais prendre explication de wayne:

<variable> = <expression> ? <true clause> : <false clause>

Lets considérer les deux cas:

case 1:
h.className += h.className ? 'true' : 'false'     
  • opérateur d'affectation fonctionne très bien et la valeur ajoutée se
  • Lors de l'exécution pour la première fois, o / p: false
  • 2ème fois. o / p: falsetrue - valeurs maintient annexant
  

affaire2:   h.className = h.className + h.className? 'True': 'false'

  • le résultat est identique cas 1
  • Lors de l'exécution pour la première fois, o / p: false
  • 2ème fois. o / p: faux - valeurs ne tiennent pas annexant

explanation

  

Dans le code ci-dessus, le cas 1 fonctionne très bien

alors que  affaire2:

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 comme opérateur ternaire est donné une priorité plus élevée. donc, toujours le résultat de l'expression ternaire est simplement attribué

Vous devez définir la priorité en utilisant des parenthèses

Vous devez définir l'ordre d'évaluation à considérer avec l'aide de crochets pour le cas 2 cas travailler 1

h.className = h.className + (h.className ? ' error' : 'error') 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top