Não consigo entender a primeira parte deste código (+ =) em combinação com o operador ternário.
h.className += h.className ? ' error' : 'error'
Acho que esse código funciona da seguinte maneira:
h.className = h.className + h.className ? ' error' : 'error'
Mas isso não está correto porque dá um erro no meu console.
Portanto, minha pergunta é como devo interpretar este código corretamente?
javascript
variable-assignment
conditional-operator
operator-precedence
compound-assignment
Baijs
fonte
fonte
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.Pense desta forma:
A forma como a instrução é executada é basicamente a seguinte:
<expression>
avaliada como verdadeira ou avaliada como falsa?<expression>
avaliado como verdadeiro, o valor de<true clause>
será atribuído a<variable>
,<false clause>
será ignorado e a próxima instrução será executada.<expression>
avaliado como falso, então<true clause>
será ignorado e o valor de<false clause>
será atribuído a<variable>
.O importante a ser percebido com o operador ternário nesta e em outras linguagens é que, qualquer que seja o código,
<expression>
deve produzir um resultado booleano quando avaliado: verdadeiro ou falso.No caso do seu exemplo, substitua "atribuído a" em minha explicação por "adicionado a", ou similar para qualquer aritmética abreviada que você esteja usando, se houver.
fonte
+
tem maior precedência do que o operador condicional / ternário (na verdade o operador condicional é quase sempre o último avaliado em qualquer expressão).O
+=
faz o que você quer, mas no enunciado ternário à direita dele, verifica seh.className
está falsey, o que seria se não estivesse definido. Se for verdade (ou seja, se um nome de classe já estiver especificado), o erro será adicionado com um espaço (ou seja, adicionando uma nova classe), caso contrário, será adicionado sem o espaço.O código pode ser reescrito como você sugere, mas você precisa especificar que
h.className
deve ser usado para comparação de veracidade, em vez de usar seu valor real, no operador ternário, portanto, certifique-se de não se preocupar com a concatenação de valores ao mesmo tempo que faz sua operação ternária:fonte
undefined
não é falso , é apenas tratado como se fosseO lado direito do
=
operador é avaliado da esquerda para a direita. Assim,é equivalente a
Para ser equivalente a
você tem que separar a declaração ternária entre parênteses
fonte
deve ser equivalente a:
fonte
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 um
error
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:
Essa deveria ter sido a resposta real para o problema real .
Seja como for, as perguntas feitas foram ...
1) Por que isso funcionou?
O operador condicional / ternário funciona como uma instrução if, que atribui o resultado de seus caminhos
true
oufalse
a uma variável.Portanto, esse código funcionou porque é avaliado simplesmente como:
2) e por que isso quebrou?
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: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árioPrecedê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).
Referência: Precedência do operador Javascript
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:
Vou deixar esta resposta para enferrujar invisível entre as outras :)
fonte
Eu gostaria de escolher a explicação de wayne:
Vamos considerar os dois casos:
explanation
enquanto caso 2:
h.className + h.className
=> considerado como expressão para o operador ternário, já que o operador ternário tem maior precedência. então, sempre o resultado da expressão ternária é apenas atribuídoVocê precisa definir a precedência usando colchetesVocê precisa definir a ordem de avaliação a ser considerada com a ajuda de colchetes para o caso 2 funcionar como o caso 1
fonte