Eu sei que esta é uma pergunta muito antiga, mas não estou 100% feliz com nenhuma das respostas, pois todas parecem incompletas. Então, aqui vamos nós de novo dos primeiros princípios:
O objetivo geral do usuário:
Resumindo o código: "Desejo adicionar umerror
nome de classe a uma string, opcionalmente com um espaço inicial se já houver nomes de classe na string."
Solução mais simples
Como Kobi apontou, 5 anos atrás, ter um espaço à esquerda nos nomes das classes não causará problemas com nenhum navegador conhecido, então a solução correta mais curta seria:
h.className += ' error';
Essa deveria ter sido a resposta real para o problema real .
Seja como for, as perguntas feitas foram ...
1) Por que isso funcionou?
h.className += h.className ? ' error' : 'error'
O operador condicional / ternário funciona como uma instrução if, que atribui o resultado de seus caminhos true
ou false
a uma variável.
Portanto, esse código funcionou porque é avaliado simplesmente como:
if (h.className IS NOT null AND IS NOT undefined AND IS NOT '')
h.className += ' error'
else
h.className += 'error'
2) e por que isso quebrou?
h.className = h.className + h.className ? ' error' : 'error'
A questão afirma "isso dá um erro [n] em meu console", o que pode induzi-lo a pensar que o código não funciona . Na verdade, o código a seguir é executado, sem erros , mas simplesmente retorna 'erro' se a string não estava vazia e 'erro' se a string estava vazia e, portanto , não atendeu aos requisitos .
Esse código sempre resulta em uma string que contém apenas ' error'
ou 'error'
porque é avaliada para este pseudocódigo:
if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
h.className = ' error'
else
h.className = 'error'
A razão para isso é que o operador de adição ( +
para o povo comum) tem maior "precedência" (6) do que o operador condicional / ternário (15). Eu sei que os números aparecem ao contrário
Precedência significa simplesmente que cada tipo de operador em uma linguagem é avaliado em uma ordem predefinida específica (e não apenas da esquerda para a direita).
Como alterar a ordem de avaliação:
Agora que sabemos por que falha, você precisa saber como fazê-lo funcionar.
Algumas outras respostas falam sobre como mudar a precedência , mas você não pode . A precedência está embutida na linguagem. Isso é apenas um conjunto fixo de regras ... No entanto, você pode alterar a ordem de avaliação ...
A ferramenta em nossa caixa de ferramentas que pode alterar a ordem de avaliação é o operador de agrupamento (também conhecido como colchetes). Ele faz isso garantindo que as expressões entre colchetes sejam avaliadas antes das operações fora dos colchetes. É tudo o que eles fazem, mas é o suficiente.
Os colchetes funcionam simplesmente porque eles (operadores de agrupamento) têm precedência mais alta do que todos os outros operadores ("agora existe um nível 0").
Simplesmente adicionando colchetes, você altera a ordem de avaliação para garantir que o teste condicional seja executado primeiro, antes da concatenação de string simples:
h.className = h.className + (h.className ? ' error' : 'error')
Vou deixar esta resposta para enferrujar invisível entre as outras :)
h.className += ' error'
, ele também deixa um espaço em branco no início da string, se ela estava inicialmente vazia. Eu acredito que o objetivo da operação ternária é produzir uma string de aparência limpa.