Sé que esta es una pregunta muy antigua, pero no estoy 100% satisfecho con ninguna de las respuestas, ya que todas parecen incompletas. Así que aquí vamos de nuevo desde los primeros principios:
El objetivo general del usuario:
Resumiendo el código: "Deseo agregar un error
nombre de clase a una cadena, opcionalmente con un espacio inicial si ya hay nombres de clase en la cadena".
La solución más sencilla
Como señaló Kobi, hace 5 años, tener un espacio inicial en los nombres de las clases no causará ningún problema con ningún navegador conocido, por lo que la solución correcta más corta sería:
h.className += ' error';
Eso debería haber sido la respuesta real al problema real .
Sea como fuere, las preguntas que se hicieron fueron ...
1) ¿Por qué funcionó esto?
h.className += h.className ? ' error' : 'error'
El operador condicional / ternario funciona como una instrucción if, que asigna el resultado de sus rutas true
o false
a una variable.
Entonces ese código funcionó porque se evalúa simplemente como:
if (h.className IS NOT null AND IS NOT undefined AND IS NOT '')
h.className += ' error'
else
h.className += 'error'
2) y ¿por qué se rompió esto?
h.className = h.className + h.className ? ' error' : 'error'
La pregunta dice "eso da un [n] error en mi consola", lo que puede inducirlo a pensar que el código no funciona . De hecho, el siguiente código se ejecuta, sin error , pero simplemente devuelve 'error' si la cadena no estaba vacía y 'error' si la cadena estaba vacía y por lo tanto no cumplía con los requisitos .
Ese código siempre da como resultado una cadena que contiene solo ' error'
o 'error'
porque evalúa este pseudo código:
if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
h.className = ' error'
else
h.className = 'error'
La razón de esto es que el operador de adición ( +
a la gente común) tiene mayor "precedencia" (6) que el operador condicional / ternario (15). Sé que los números aparecen al revés
Precedencia simplemente significa que cada tipo de operador en un idioma se evalúa en un orden predefinido particular (y no solo de izquierda a derecha).
Cómo cambiar el orden de evaluación:
Ahora que sabemos por qué falla, necesita saber cómo hacer que funcione.
Algunas otras respuestas hablan de cambiar la precedencia , pero no puedes . La precedencia está integrada en el idioma. Eso es solo un conjunto fijo de reglas ... Sin embargo, puede cambiar el orden de evaluación ...
La herramienta de nuestra caja de herramientas que puede cambiar el orden de evaluación es el operador de agrupación (también conocido como corchetes). Para ello, se asegura de que las expresiones entre corchetes se evalúen antes de las operaciones fuera de los corchetes. Eso es todo lo que hacen, pero es suficiente.
Los corchetes funcionan simplemente porque ellos (operadores de agrupación) tienen mayor precedencia que todos los demás operadores ("ahora hay un nivel 0").
Simplemente agregando corchetes, cambia el orden de evaluación para garantizar que la prueba condicional se realice primero, antes de la concatenación de cadenas simple:
h.className = h.className + (h.className ? ' error' : 'error')
Ahora dejaré esta respuesta para que no se vea entre las demás :)
h.className += ' error'
, también deja un espacio en blanco al comienzo de la cadena si inicialmente estaba vacío. Creo que el objetivo de la operación ternaria es producir una cuerda de aspecto limpio.