var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Eu vi em uma resposta e nunca vi antes.
O que isso significa?
javascript
syntax
bit-manipulation
wwaawaw
fonte
fonte
Respostas:
~
é um operador bit a bit que inverte todos os bits em seu operando.Por exemplo, se seu número fosse
1
, sua representação binária do flutuador IEEE 754 (como JavaScript trata os números) seria ...Portanto,
~
converte seu operando em um número inteiro de 32 bits (operadores bit a bit em JavaScript fazem isso) ...Se fosse um número negativo, seria armazenado no complemento de 2: inverta todos os bits e adicione 1.
... e depois vira todos os seus bits ...
Tem alguns usos. Se você está escrevendo coisas de baixo nível, é útil. Se você definiu o perfil do seu aplicativo e encontrou um gargalo, ele poderia ter um desempenho melhor usando truques bit a bit (como uma ferramenta possível em um pacote muito maior).
É também uma (geralmente) claro truque para transformar
indexOf()
's encontrados valor de retorno em truthy (ao fazer não encontrado como Falsas ) e muitas vezes as pessoas usá-lo para seu efeito colateral de truncar números para 32 bits (e soltando sua casa decimal, duplicando-a, efetivamente o mesmo queMath.floor()
para números positivos).Digo claro porque não é imediatamente óbvio para o que está sendo usado. Geralmente, você deseja que seu código se comunique claramente com outras pessoas que o leem. Embora o uso
~
possa parecer legal , geralmente é inteligente demais para o seu próprio bem. :)Também é menos relevante agora que JavaScript
Array.prototype.includes()
eString.prototype.includes()
. Eles retornam um valor booleano. Se a (s) sua (s) plataforma (s) de destino o suportarem, você deve preferir isso para testar a existência de um valor em uma string ou matriz.fonte
value = value || default
, o JavaScript é um idioma comum e válido, desde que você saiba quando pode e não pode usá-lo.v = t ? a : b;
. Eu acho isso muito mais claro do quevar v; if (t} { v = a; } else { v = b; }
normalmente dividido em mais de 5 linhas e também mais claro dovar v = b; if (t) { v = a; }
que o que normalmente seria 4+ linhas. Mas conheço muitas pessoas não familiarizadas com os? :
operadores que preferem a segunda ou terceira via. Acho que o primeiro é mais legível. Eu concordo com o princípio geral, deixe o código claro, não use hacks. Eu acho que só fico~v.indexOf('...')
muito claro depois de aprender.~
idiomático. é tecnicamente parte das especificações do idioma , mas não faz parte do idioma em uso geral .Usá-lo antes de uma
indexOf()
expressão efetivamente fornece um resultado de verdade / falsidade em vez do índice numérico retornado diretamente.Se o valor de retorno for
-1
, então~-1
é0
porque-1
é uma sequência de todos os 1 bits. Qualquer valor maior ou igual a zero dará um resultado diferente de zero. Portanto,causará o
if
código seja executado quando "algo" estiver em "someString". Se você tentar usar.indexOf()
como um booleano diretamente, isso não funcionará porque, às vezes, retorna zero (quando "algo" está no início da string).Obviamente, isso também funciona:
e é consideravelmente menos misterioso.
Às vezes, você também verá isso:
Usar o
~
operador duas vezes como esse é uma maneira rápida de converter uma string em um número inteiro de 32 bits. O primeiro~
faz a conversão e o segundo~
inverte os bits. Obviamente, se o operador for aplicado a algo que não pode ser convertido em um número, você obtém oNaN
resultado. ( editar - na verdade, é o segundo~
que é aplicado primeiro, mas você entendeu.)fonte
~
quando executado em números inteiros é igual a-(x + 1)
.0
serfalse
e ser diferente de zerotrue
remonta há muito tempo, pelo menos a C nos anos 70 e provavelmente muitas outras linguagens de programação de sistemas então contemporâneas. Provavelmente decorre da maneira como o hardware funciona; Muitas CPUs definem um bit zero após uma operação e possuem uma instrução de ramificação correspondente para testá-lo.| 0
, nesse caso, sua única operação.~~
mesma maneira.O operador
~
é Bitwise NOT ,~x
é aproximadamente o mesmo que-(x+1)
. É mais fácil entender, mais ou menos. Assim:Considere
-(x+1)
.-1
pode executar essa operação para produzir a0
.Em outras palavras, o
~
uso com um intervalo de valores numéricos produzirá um valor de falsificação (coagir afalse
partir de0
) apenas para o-1
valor de entrada; caso contrário, qualquer outro valor de verdade.Como sabemos,
-1
é comumente chamado de valor sentinela . Ele é usado para muitas funções que retornam>= 0
valores para o sucesso e-1
para a falha na linguagem C. Qual a mesma regra de retornoindexOf()
em JavaScript.É comum verificar a presença / ausência de uma substring em outra string dessa maneira
No entanto, seria mais fácil fazê-lo
~
como abaixoVocê não conhece JS: Tipos e gramática por Kyle Simpson
fonte
-(x+1)
se a vi em uma declaração if. O til me diz exatamente o que está fazendo para compensar a natureza baseada em 0 do Javascript. Além disso, quanto menos parênteses, melhor para a leituraif (a.indexOf("Ba") > -1) {// found} //true
qual, embora um pouco mais longo que os exemplos til, é consideravelmente menor do que os dois exemplos que você deu e évar opinion = !~-1 ? 'more' : 'less'
compreensível para novos programadores .~indexOf(item)
aparece com bastante frequência, e as respostas aqui são ótimas, mas talvez algumas pessoas precisem saber como usá-lo e "pular" a teoria:fonte
++
e--
porque eles "incentivar trickiness excessiva" e ainda de alguma forma~
sobreviveram (à espreita nas sombras) github.com/airbnb/javascript/issues/540list.indexOf(item) >= 0
ou... > -1
já que o javascript é baseado em zero e não optou por resolver isso desde o início. Além disso, apenas a opinião (igual à do Airbnb), qualquer pessoa que esteja fazendo algo significativo em javascript sabe++
e, embora--
seja menos comum, o significado pode ser inferido.++
e--
em um tempo por causa de métodos primitivos comomap
,forEach
etc. Meu ponto é mais sobre por que não também considerar~
excessivamente complicado quando tudo o padrão usado inclui incremento e operadores decréscimo. Proibir algo para que o CIS101 não faça sentido.Para aqueles que consideram usar o truque til para criar um valor verdadeiro a partir de um
indexOf
resultado, é mais explícito e tem menos mágica para usar oincludes
métodoString
.Observe que esse é um novo método padrão a partir do ES 2015, portanto não funcionará em navegadores mais antigos. Nos casos em que isso for importante, considere usar o polyfill String.prototype.includes .
Esse recurso também está disponível para matrizes usando a mesma sintaxe :
Aqui está o polyfill Array.prototype.includes, se você precisar de suporte mais antigo ao navegador.
fonte