Pergunta

Parece que não consigo entender a primeira parte deste código ( +=) em combinação com o operador ternário.

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

A maneira como acho que esse código funciona é o seguinte:

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

Mas isso não está correto porque isso dá um erro no meu console.

Então, minha pergunta é como devo interpetir esse código corretamente?

Foi útil?

Solução

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

Você quer que o operador trabalhe para h.className, é melhor ser específico sobre isso.
Claro, nenhum dano deve vir de h.className += ' error', mas isso é outra questão.

Além disso, observe que + tem precedência sobre o operador ternário: Precedência do operador JavaScript

Outras dicas

Pense desta maneira:

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

A maneira como a declaração é executada é basicamente a seguinte:

  1. Faz <expression> Avalie o verdadeiro, ou avalia como falso?
  2. Se <expression> avalia como verdadeiro, então o valor de <true clause> é atribuído a <variable>, <false clause> é ignorado e a próxima declaração é executada.
  3. Se <expression> avalia para false, então <true clause> é ignorado e o valor de <false clause> é atribuído a <variable>.

O importante a perceber com o operador ternário neste e em outras línguas é que qualquer código esteja em <expression> deve produzir um resultado booleano quando avaliado: verdadeiro ou falso.

No caso do seu exemplo, substitua "atribuído a" na minha explicação com "Adicionado a", ou similar por qualquer aritmética abreviada que você esteja usando, se houver.

o += faz o que você quer, mas na declaração ternária à direita, ele verifica se h.className é falso, o que seria se fosse indefinido. Se for verdade (ou seja, se um nome de classe já estiver especificado), o erro será adicionado com um espaço (ou seja, adicionando um novo classe), caso contrário, é 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 verunhura, em vez de usar seu valor real, no operador ternário, portanto, não se preocupe com a concatenação de valores ao mesmo tempo em que sua operação ternária:

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

O lado direito do = O operador é avaliado da esquerda para a direita. Então,

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

é equivalente a

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

Ser equivalente a

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

Você tem que separar a declaração ternária entre parênteses

h.className = h.className + (h.className ? ' error' : 'error');
if (h.className) {
    h.className = h.className + ' error';
} else {
    h.className = h.className + 'error';
}

deve ser equivalente a:

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

Sei que essa é uma pergunta muito antiga, mas não estou 100% feliz com nenhuma das respostas, pois todas elas parecem incompletas. Então, aqui vamos nós novamente dos primeiros diretores:

O objetivo geral do usuário:

Resumindo o código: "Eu gostaria de adicionar um error Nome da classe em uma string, opcionalmente com um espaço líder se já houver nomes de classe na string. "

Solução mais simples

Como Kobi apontou, há 5 anos, ter um espaço líder em nomes de classe não causará problemas com nenhum navegador conhecido; portanto, a solução mais curta correta seria realmente:

h.className += ' error';

Isso deveria ter sido o 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 declaração IF, que atribui o resultado de seu true ou false caminhos para uma variável.

Então 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 pergunta afirma "que dá um erro [n] no meu console", o que pode induzi -lo a pensar no código não funciona. De fato, o código a seguir é executado, sem erro, mas simplesmente retorna 'erro' se a string não foi vazio e 'erro' se a string foi vazio e assim não atendeu aos requisitos.

Esse código sempre resulta em uma string que contém apenas ' error' ou 'error' Porque ele avalia para este código pseudo:

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 para trás

Precedência significa simplesmente que cada tipo de operador em um idioma é 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 da avaliação:

Agora sabemos por que falha, você precisa saber como fazê -lo funcionar.

Algumas outras respostas falam sobre mudando a precedência, mas você não pode. Precedência é conectada à língua. Esse é apenas um conjunto fixo de regras ... no entanto, você pode alterar o 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 suportes). Faz isso, garantindo que as expressões entre os colchetes sejam avaliadas antes da operações fora dos colchetes. Isso é tudo o que eles fazem, mas isso é o suficiente.

Suportes funcionam simplesmente porque (operadores de agrupamento) têm maior precedência do que todos os outros operadores ("Agora existe um nível 0").

Simplesmente adicionando suportes você Alterar a ordem de avaliação Para garantir que o teste condicional seja realizado primeiro, antes da concatenação simples de string:

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

Agora vou deixar esta resposta para Rust Invision entre os outros :)

Eu gostaria de escolher a explicação de Wayne:

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

Vamos considerar os dois casos:

case 1:
h.className += h.className ? 'true' : 'false'     
  • O operador de atribuição funciona bem e o valor é anexado
  • Quando corre pela primeira vez, o/p: false
  • 2ª vez. O/P: Falsetue - Valores continuam anexando

case2: h.className = h.className + h.className? 'verdadeiro falso'

  • O resultado não é o mesmo que o caso 1
  • Quando corre pela primeira vez, o/p: false
  • 2ª vez. o/p: false - valores não continuam anexando

explanation

No código acima, o caso 1 funciona bem

Considerando que Case2:

h.className = h.className + h.className ? 'true' : 'false'
is executed as 
 h.className = (h.className + h.className) ? 'true' : 'false'

h.className + h.className => considerado como expressão para operador ternário como operador ternário recebe maior precedência. Então, sempre o resultado da expressão ternária é atribuída

Você precisa definir a precedência usando colchetes

Você precisa definir a ordem de avaliação a ser considerada com a ajuda de colchetes para o caso 2 funcionar como Caso 1

h.className = h.className + (h.className ? ' error' : 'error') 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top