javascript - script - || node js




O que é !! operador(não não) em JavaScript? (20)

! é "boolean not", que essencialmente tiporna o valor de "enable" para o seu oposto booleano. O segundo ! inverte este valor. Então, !!enable significa "não não ativar", dando a você o valor de enable como booleano.

Eu vi um código que parece usar um operador que não reconheço, na forma de dois pontos de exclamação, assim: !! . Alguém pode me dizer o que esse operador faz?

O contexto em que vi isso foi,

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

É apenas o operador NOT lógico, duas vezes - é usado para converter algo em booleano, por exemplo:

true === !!10

false === !!0

É uma maneira horrivelmente obscura de fazer uma conversão de tipo.

! NÃO é. Então, !true é false e !false é true . !0 é true e !1 é false .

Então você está convertendo um valor para um booleano, depois invertendo-o e, em seguida, invertendo-o novamente.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

Alguns operadores em JavaScript realizam conversões de tipo implícitas e, às vezes, são usados ​​para conversão de tipo.

O unário ! operador converte seu operando em um booleano e o nega.

Esse fato leva ao seguinte idioma que você pode ver no seu código-fonte:

!!x // Same as Boolean(x). Note double exclamation mark

Coerces oObject to boolean. Se foi falsey (por exemplo, 0, null , undefined , etc), será false , caso contrário, true .

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

Então !! não é um operador, é apenas o ! operador duas vezes.

Exemplo do mundo real "Test IE version":

let isIE8 = false;  
isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

Se você ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns null  

mas se você ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns true or false

Converte o sufixo em um valor booleano.


Eu acho que vale a pena mencionar, que uma condição combinada com lógica AND / OR não retornará um valor booleano, mas o último sucesso ou falha primeiro em caso de && e primeiro sucesso ou falha final em caso de || da cadeia de condição.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

Para lançar a condição para um verdadeiro literal booleano, podemos usar a negação dupla:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

Eu suspeito que isso é uma sobra de C + + onde as pessoas substituem o! operador, mas não o operador bool.

Então, para obter uma resposta negativa (ou positiva), nesse caso, você primeiro precisa usar o! operador para obter um booleano, mas se você quisesse verificar o caso positivo usaria !!


Negação booleana dupla. Geralmente usado para verificar se o valor não é indefinido.


O !! A construção é uma maneira simples de transformar qualquer expressão JavaScript em seu equivalente booleano.

Por exemplo: !!"he shot me down" === true e !!0 === false .


Retorna o valor booleano de uma variável.

Em vez disso, Boolean classe Boolean pode ser usada.

(por favor leia as descrições do código)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

Ou seja, Boolean(X) = !!X em uso.

Por favor verifique o código trecho abaixo

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true


Tantas respostas fazendo metade do trabalho. Sim, !!X poderia ser lido como "a autenticidade de X [representada como booleana]". Mas !! não é, praticamente falando, tão importante para descobrir se uma única variável é (ou mesmo se muitas variáveis ​​são) verdadeira ou falsamente. !!myVar === true é o mesmo que myVar . Comparar !!X a um booleano "real" não é realmente útil.

O que você ganha com !! é a capacidade de verificar a autenticidade de várias variáveis entre si de uma maneira padronizada (e amigável à JSLint).

Simplesmente lançando :(

Isso é...

  • 0 === false é false .
  • !!0 === false é true .

O acima não é tão útil. if (!0) fornece os mesmos resultados como if (!!0 === false) . Eu não consigo pensar em um bom caso para converter uma variável para boolean e, em seguida, comparando com um booleano "true".

Veja "== e! =" A partir das instruções do JSLint (nota: Crockford está movendo seu site um pouco; esse link está sujeito a morrer em algum momento) por um pouco sobre o porquê:

Os operadores == e! = Fazem coerção antes de comparar. Isso é ruim porque faz com que '\ t \ r \ n' == 0 seja verdadeiro. Isso pode mascarar erros de tipo. O JSLint não pode determinar com segurança se == está sendo usado corretamente, portanto, é melhor não usar == e! = De forma alguma e sempre usar os operadores mais confiáveis ​​=== e! ==.

Se você apenas se importa que um valor seja verdadeiro ou falso, então use o formulário curto. Ao invés de
(foo != 0)

apenas diga
(foo)

e em vez de
(foo == 0)

dizer
(!foo)

Observe que há alguns casos não intuitivos em que um booleano será convertido em um número ( true é convertido para 1 e false para 0 ) ao comparar um valor booleano com um número. Neste caso, !! pode ser mentalmente útil. Porém, novamente, esses são casos em que você está comparando um não-booleano a um booleano tipado, o que é um erro grave. if (-1) ainda é o caminho a percorrer aqui.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               Original                ║    Equivalent     ║  Result   ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam")   ║ if (-1 == 1)      ║ undefined ║
║ if (-1 == false) console.log("spam")  ║ if (-1 == 0)      ║ undefined ║
║   Order doesn't matter...             ║                   ║           ║
║ if (true == -1) console.log("spam")   ║ if (1 == -1)      ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam      ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam")           ║ if (truthy)       ║ spam      ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

E as coisas ficam ainda mais loucas dependendo do seu motor. O WScript, por exemplo, ganha o prêmio.

function test()
{
    return (1 === 1);
}
WScript.echo(test());

Por causa de algum histórico do Windows , ele gerará -1 em uma caixa de mensagem! Tente em um prompt de cmd.exe e veja! Mas WScript.echo(-1 == test()) ainda dá 0, ou WScript é false . Olhe para longe. É horrível.

Comparando a verdade :)

Mas, e se eu tiver dois valores, preciso verificar a verdade e a falsidade iguais?

Finja que temos myVar1 = 0; e myVar2 = undefined; .

  • myVar1 === myVar2 é 0 === undefined e é obviamente falso.
  • !!myVar1 === !!myVar2 é !!0 === !!undefined e é verdade! Mesma autenticidade! (Neste caso, ambos "têm uma veracidade de falsidade".)

Então o único lugar onde você realmente precisaria usar "variáveis ​​boolean-cast" seria se você tivesse uma situação em que você estivesse checando se ambas as variáveis ​​tinham a mesma verdade, certo? Ou seja, use !! se você precisa ver se duas vars são verdadeiras ou falsas (ou não), isto é, de igual (ou não) verdade .

Não consigo pensar em um ótimo caso de uso não planejado para esse improviso. Talvez você tenha "vinculado" campos em um formulário?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age " 
        + "for your spouse or leave all spouse fields blank.";
}

Então, agora, se você tiver um trunfo para ambos ou um falso para o nome e a idade do cônjuge, você pode continuar. Caso contrário, você só terá um campo com um valor (ou um casamento arranjado muito cedo) e precisará criar um erro extra na sua coleção errorObjects .

EDIT 24 out 2017:

Bibliotecas de terceiros que esperam valores Booleanos explícitos

Aqui está um caso interessante ... !! pode ser útil quando libs de terceiros esperam valores Booleanos explícitos.

Por exemplo, False em JSX (React) tem um significado especial que não é acionado em falsidades simples. Se você tentou retornar algo como o seguinte no seu JSX, esperando um int na messageCount ...

{messageCount && <div>You have messages!</div>}

... você pode se surpreender ao ver React renderizar um 0 quando você tiver zero mensagens. Você precisa explicitamente retornar falso para JSX para não renderizar. A declaração acima retorna 0 , que JSX processa de maneira feliz, como deveria. Não é possível dizer que você não tem Count: {messageCount && <div>Get your count to zero!</div>} (ou algo menos planejado).

  • Uma correção envolve o bangbang, que coage 0 em !!0 , o que é false :
    {!!messageCount && <div>You have messages!</div>}

  • Os documentos do JSX sugerem que você seja mais explícito, escreva código de auto-comentário e use uma comparação para forçar um booleano.
    {messageCount > 0 && <div>You have messages!</div>}

  • Estou mais confortável lidando com falsidade com um ternário -
    {messageCount ? <div>You have messages!</div> : false}

Tenha em mente que esta é uma convenção JSX , não uma inerente ao JavaScript .

Mas se você ver estranhos 0 s no seu JSX renderizado, pense em gerenciar falsamente.


aqui está um pedaço de código de js angular

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;

sua intenção é definir rafSupported como true ou false com base na disponibilidade de função em requestAnimationFrame

pode ser conseguido fazendo o check-in da seguinte maneira em geral:

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

o caminho mais curto poderia estar usando !!

rafSupported = !!requestAnimationFrame ;

então se requestAnimationFrame foi atribuído a uma função então! requestAnimationFrame seria falso e mais um! disso seria verdade

Se requestAnimationFrame foi considerado indefinido, então! requestAnimationFrame seria verdadeiro e mais um! seria falso


!! converte o valor à direita dele para seu valor booleano equivalente. (Pense na maneira do pobre homem de "fundição de tipos"). Sua intenção é geralmente transmitir ao leitor que o código não importa qual valor está na variável, mas qual é o valor da "verdade" .


!!é semelhante a usar o construtor booleano ou, possivelmente, mais como a função booleana.

console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

Os valores de Falsey no javascript são coagidos para valores falsos e os valores verdadeiros são coagidos para true. Os valores de Falsey e Truthy também podem ser usados ​​em ifinstruções e essencialmente "mapear" para seu valor booleano correspondente. No entanto, você provavelmente não terá que usar valores booleanos adequados com frequência, pois eles diferem na saída (valores de retorno).

Embora isso possa parecer semelhante ao elenco, realisticamente, isso é provavelmente uma mera coincidência e não é 'construído' ou propositalmente feito para e como um elenco booleano. Então não vamos chamar assim.

Por que e como funciona

Para ser conciso, que é algo como isto: ! ( !null ). Considerando que, nullé falsey , isso !nullseria verdade . Então !trueseria falso e essencialmente inverteria de volta ao que era antes, exceto desta vez como um valor booleano apropriado (ou mesmo vice-versa com valores verdadeiros como {}ou 1).


Voltando ao seu exemplo

No geral, o contexto que você viu simplesmente se ajusta, this.verticaldependendo de verticalestar definido ou não , e se sim; ele será definido para o valor booleano resultante de vertical, caso contrário, ele não será alterado. Em outras palavras, se verticalé definido; this.verticalserá definido para o valor booleano dele, caso contrário, ele permanecerá o mesmo. Eu acho que em si é um exemplo de como você usaria !!, e o que faz.


Exemplo de E / S Vertical

Execute este exemplo e mexer com o valor vertical na entrada. Veja o que o resultado faz para que você possa entender completamente o código do seu contexto. Na entrada, insira qualquer valor válido de javascript. Lembre-se de incluir as cotações se você estiver testando uma string. Não se importe muito com o código CSS e HTML, basta executar este snippet e brincar com ele. No entanto, talvez você queira dar uma olhada no código javascript não relacionado ao DOM (o uso do construtor Example e da variável vertical).

var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>


!!expr retorna um valor booleano ( true ou false ) dependendo da veracidade da expressão. Faz mais sentido quando usado em tipos não booleanos. Considere estes exemplos, especialmente o terceiro exemplo e adiante:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

!!x é uma forma abreviada de Boolean(x)

O primeiro estrondo força o mecanismo js a executar Boolean(x) mas também tem o efeito colateral de inverter o valor. Então o segundo estrondo desfaz o efeito colateral.


Brew algum chá:

!! não é um operador. É o duplo uso de ! - que é o operador "não" lógico.

Em teoria:

! determina a "verdade" do que um valor não é:

  • A verdade é que false não é true (é por isso que !false resultados são true )

  • A verdade é que a true não é false (é por isso que os resultados !true são false )

!! determina a "verdade" do que um valor não é:

  • A verdade é que a true não é true (é por isso que os !!true resultados são true )

  • A verdade é que false não é false (é por isso que !!false resultados são false )

O que desejamos determinar na comparação é a "verdade" sobre o valor de uma referência, não o valor da própria referência. Há um caso de uso em que podemos querer saber a verdade sobre um valor, mesmo se esperamos que o valor seja false (ou falsey), ou se esperamos que o valor não seja typeof boolean .

Na prática:

Considere uma função concisa que detecta a funcionalidade do recurso (e, neste caso, a compatibilidade da plataforma) por meio de digitação dinâmica (também conhecida como "digitação de pato"). Queremos escrever uma função que retorne true se o navegador de um usuário suportar o elemento HTML5 <audio> , mas não queremos que a função lance um erro se <audio> for indefinido; e nós não queremos usar try ... catch para lidar com possíveis erros (porque eles são grosseiros); e também não queremos usar uma verificação dentro da função que não revelará consistentemente a verdade sobre o recurso (por exemplo, document.createElement('audio') ainda criará um elemento chamado <audio> mesmo se HTML5 <audio> não é suportado).

Aqui estão as três abordagens:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Cada função aceita um argumento para um <tag> e um attribute para procurar, mas cada um retorna valores diferentes com base no que as comparações determinam.

Mas espere, tem mais!

Alguns de vocês provavelmente notaram que neste exemplo específico, alguém poderia simplesmente verificar uma propriedade usando o meio com um pouco mais de desempenho de verificar se o objeto em questão tem uma propriedade. Existem duas maneiras de fazer isso:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

Nós divagamos ...

Por mais raras que sejam essas situações, pode haver alguns cenários em que os meios mais concisos, mais eficazes e, portanto, mais preferidos, de se obter um valor não-booleano, possivelmente indefinido, sejam de fato usando !! . Espero que isso seja ridiculamente claro.


Eu só queria acrescentar isso

if(variableThing){
  // do something
}

é o mesmo que

if(!!variableThing){
  // do something
}

Mas isso pode ser um problema quando algo é indefinido.

// a is undefined, b is empty object.
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

O truque aqui é que a cadeia de &&s retornará o primeiro valor de falsey que encontrar - e isso pode ser alimentado para uma declaração if etc. Então, se b.foo for indefinido, ele retornará indefinido e ignorará a b.foo.bardeclaração, e nós não obteremos erro.

O retorno acima é indefinido, mas se você tiver uma string vazia, false, null, 0, undefined, esses valores retornarão e logo que os encontrarmos na cadeia - []e {}ambos são verdadeiros.


Use lógico não operador duas vezes
isso significa! True = false
e !! true = true







operators