Operator precedence with Javascript Ternary operator
I cant seem to wrap my head around the first part of this code ( += ) in combination with the ternary operator.
h.className += h.className ? ' error' : 'error'
The way i think this code works is as following:
h.className = h.className + h.className ? ' error' : 'error'
But that isn't correct because that gives a error in my console.
So my question is how should i interpet this code correctly?
h.className = h.className + (h.className ? ' error' : 'error')
You want the operator to work for h.className
, better be specific about it.
Of course, no harm should come from h.className += ' error'
, but that's another matter.
Also, note that +
has precedence over the ternary operator: JavaScript Operator Precedence
Think of it this way:
<variable> = <expression> ? <true clause> : <false clause>
The way the statement gets executed is basically as follows:
- Does
<expression>
evaluate to true, or does it evaluate to false? - If
<expression>
evaluates to true, then the value of<true clause>
is assigned to<variable>
,<false clause>
is ignored, and the next statement is executed. - If
<expression>
evaluates to false, then<true clause>
is ignored and the value of<false clause>
is assigned to<variable>
.
The important thing to realise with the ternary operator in this and other languages is that whatever code is in <expression>
should produce a boolean result when evaluated: either true or false.
In the case of your example replace "assigned to" in my explanation with "added to", or similar for whichever shorthand arithmetic you are using, if any.
The +=
does what you want, but in the ternary statement at the right hand of it, it checks if h.className
is falsey, which it would be if it was undefined. If it's truthy (i.e. if a class name is already specified), then error is added with a space (i.e. adding a new class), otherwise it's added without the space.
The code could be rewritten as you suggest, but you need to specify that h.className
is to be used for truthiness-comparison, rather than for using its actual value, in the ternary operator, so make sure you don't bother with the concatenation of values at the same time as doing your ternary operation:
h.className = h.className + (h.className ? ' error' : 'error');
The right hand side of the =
operator is evaluated left to right. So,
g.className = h.className + h.className ? ' error' : 'error';`
is equivalent to
h.className = (h.className + h.className) ? ' error' : 'error';
To be equivalent to
h.className += h.className ? ' error' : 'error';
you have to separate the ternary statement in parenthesis
h.className = h.className + (h.className ? ' error' : 'error');
if (h.className) {
h.className = h.className + ' error';
} else {
h.className = h.className + 'error';
}
should be equivalent of:
h.className += h.className ? ' error' : 'error';