Cuál es el !! (no no) operador en JavaScript?

Vi un código que parece usar un operador que no reconozco, en forma de dos signos de exclamación, así: !!. ¿Alguien puede decirme qué hace este operador?

El contexto en el que vi esto fue,

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

preguntado el 24 de abril de 09 a las 05:04

Recuérdalo con "bang, bang, eres booleano" -

Solo para que conste, no hagas lo que se cita allí. Hacer if(vertical !== undefined) this.vertical = Boolean(vertical); - Es mucho más limpio y claro lo que está sucediendo, no requiere asignaciones innecesarias, es completamente estándar y es igual de rápido (en FF y Chrome actuales) jsperf.com/boolean-conversion-speed . -

!! no es un operador. ¡Es solo el! operador dos veces. -

@schabluk, para que conste, Orden de operaciones es la razón !!5/0 produce Infinity más bien que true, según lo producido por Boolean(5/0). !!5/0 es equivalente a (!!5)/0 - alias true/0 -- debido a la ! operador que tiene una precedencia mayor que el / operador. Si quisieras Booleanizar 5/0 usando un doble golpe, necesitarías usar !!(5/0). -

@Gus Para que lo sepas, leí tu comentario en 2012. En el transcurso de los 7 años transcurridos desde entonces, siempre he dicho con humor en mi mente "¡Bang bang! ¡Eres booleano!" al invertir un booleano, y siempre he recordado cómo como resultado. Decidí buscar tu comentario hoy y hacerte saber :-) -

30 Respuestas

Convierte Object a boolean. Si fue falso (p. Ej. 0, null, undefined, etc.), será falsede lo contrario true.

!oObject  // inverted boolean
!!oObject // non inverted boolean so true boolean representation

So !! no es un operador, es solo el ! operador dos veces.

Ejemplo del mundo real "Prueba de la versión de IE":

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

Si tu ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

Pero si tu ⇒

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

Respondido 07 Feb 20, 11:02

Convierte un booleano no booleano en un booleano invertido (por ejemplo,! 5 sería falso, ya que 5 es un valor no falso en JS), luego boolean-invierte eso para obtener el valor original como booleano (entonces !! 5 sería ser cierto). - Arrojar

Una forma fácil de describirlo es: Boolean (5) === !! 5; Mismo reparto, menos personajes. - Micah Snyder

Esto se usa para convertir valores verdaderos a booleanos verdaderos y valores falsos demasiado booleanos falsos. - elherramienta

@Micah Snyder tenga cuidado de que en JavaScript es mejor usar primitivas booleanas en lugar de crear objetos que recubren booleanos con new Boolean (). Aquí tienes un ejemplo para ver la diferencia: jsfiddle.net/eekbu - victorvartan

Hasta donde yo sé, este patrón bang-bang no es útil dentro de una declaración if (… _; solo en una declaración de retorno de una función que debería devolver un valor booleano. rds

Es una forma horriblemente oscura de hacer una conversión de tipos.

! is NO . Asi que !true is falsey !false is true. !0 is truey !1 is false.

Por lo tanto, está convirtiendo un valor en un valor booleano, luego lo invierte y luego lo vuelve a invertir.

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

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

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

Respondido el 26 de Septiembre de 11 a las 15:09

!! falso = falso. !! verdadero = verdadero - cierre

¿Es la variante "mucho más fácil de entender" realmente mucho más fácil de entender aquí? La verificación contra 0 no es una verificación real contra 0, sino una verificación contra la lista algo extraña de valores que Javascript considera iguales a 0. userId ? true : false deja más claro que se está realizando una conversión y maneja el caso en el que el valor de userId podría haberse establecido explícitamente en undefined - ben regenspan

Mi cerebro no tiene problemas para decodificar !!var dentro Boolean(var) .. y !! es más rápido (menos instrucciones para procesar) y más corto que las alternativas. - AdamJLev

!!false Es falso. false != 0 es verdad. Entonces no son equivalentes. !! cumple el útil propósito de coaccionar cualquier cosa a un booleano. - Delgado

Me doy cuenta de que escribió esta respuesta hace muchos años, pero con el interés de refinarla para hoy: lo más fácil de entender es di lo que quieres decir: Boolean(x). No considero que ninguna de sus alternativas sea fácil de entender. Peor aún, hay al menos un caso en el que se usa el operador de igualdad x != 0 da un resultado diferente al Boolean(x) or !!x: tratar [] para x. Además, si le gusta usar el operador de igualdad, para obtener sus reglas de "veracidad", ¿por qué no haría lo más obvio (userId == true) en lugar de (userId != 0)? - Fabricante de herramientasSteve

!!expr devuelve un valor booleano (true or false) dependiendo de la verdad de la expresión. Tiene más sentido cuando se usa en tipos no booleanos. Considere estos ejemplos, especialmente el tercer ejemplo en adelante:

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

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy
          !!(1/0) === true  // Infinity 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!

Respondido 07 ago 20, 20:08

Cabe destacar: !!new Boolean(false) // true - Camilo Martín

...Pero también !!Boolean(false) // false - Camilo Martín

new Boolean(false) es un objeto y un objeto es verdadero incluso si contiene un valor falso. - salman a

Prepara un poco de té:

!! no es un operador. Es el doble uso de ! - que es el operador lógico "no".


En teoria:

! determina la "verdad" de lo que un valor no es:

  • La verdad es esa false no está true (es por eso !false resultados en true)

  • La verdad es esa true no está false (es por eso !true resultados en false)


!! determina la "verdad" de lo que es un valor no no:

  • La verdad es esa true no está no true (es por eso !!true resultados en true)

  • La verdad es esa false no está no false (es por eso !!false resultados en false)


Lo que deseamos determinar en la comparación es la "verdad" sobre nosotros el valor de una referencia, no el valor de la referencia en sí. Hay un caso de uso en el que podríamos querer saber la verdad sobre un valor, incluso si esperamos que el valor sea false (o falsey), o si esperamos que el valor no sea del tipo boolean.


En la práctica:

Considere una función concisa que detecta la funcionalidad de la característica (y en este caso, la compatibilidad de la plataforma) por medio de escritura dinámica (también conocido como "escritura de pato"). Queremos escribir una función que devuelva true si el navegador de un usuario es compatible con HTML5 <audio> elemento, pero no queremos que la función arroje un error si <audio> es indefinido; y no queremos usar try ... catch para manejar los posibles errores (porque son graves); y también no queremos usar un cheque dentro de la función que no revelará consistentemente la verdad sobre la característica (por ejemplo, document.createElement('audio') seguirá creando un elemento llamado <audio> incluso si HTML5 <audio> no es apoyado).


Estos son los tres enfoques:

// 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 función acepta un argumento para un <tag> y una attribute buscar, pero cada uno devuelve valores diferentes en función de lo que determinan las comparaciones.

¡Pero espera, hay más!

Algunos de ustedes probablemente notaron que en este ejemplo específico, uno podría simplemente verificar una propiedad usando el leve más eficiente medios de comprobar si el objeto en cuestión tiene una propiedad. Hay dos maneras de hacer esto:

// 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

Divagamos ...

No importa cuán raras sean estas situaciones, pueden existir algunos escenarios en los que los medios más concisos, más eficaces y, por lo tanto, más preferidos para obtener true de un valor no booleano, posiblemente indefinido, es de hecho mediante el uso de !!. Ojalá esto lo aclare ridículamente.

Respondido 22 Feb 13, 23:02

respuesta totalmente impresionante, pero no veo la utilidad del !! construir. Desde un if() declaración ya convierte la expresión en booleano, convertir explícitamente el valor de retorno de una función de prueba en booleano es redundante, ya que "sinceridad" === verdadero en cuanto a if() declaración va de todos modos. ¿O me estoy perdiendo un escenario en el que NECESITAS una expresión veraz para ser realmente booleano? true? - barrena tom

@TomAuger if() las declaraciones emiten valores booleanos contra falsey, pero digamos que realmente desea establecer una bandera booleana en un objeto; no lo emitirá como un if() declaración lo hace. Por ejemplo object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat() establecería ya sea true or false en lugar del valor de retorno real. Otro ejemplo es que tal vez todos los administradores id of 0 y los no administradores son id 1 o mas alto. Llegar true si alguien no es un administrador, puede hacerlo person.isNotAdmin = !!admin.id. Pocos casos de uso, pero es conciso cuando lo hay. - Benny

!! convierte el valor a su derecha en su valor booleano equivalente. (Piense en la forma de "tipificar" de los pobres). Su intención es generalmente para transmitir al lector que al código no le importa qué el valor está en la variable, pero lo que es "valor de verdad .

Respondido el 10 de Septiembre de 09 a las 18:09

O en el caso de un valor booleano a la derecha, no hace nada. - Daniel A. Blanco

@Daniel: ! todavía invierte el valor a la derecha. En el caso de un booleano, el más a la derecha ! niega el valor, mientras que el más a la izquierda ! lo niega una vez más. El efecto neto es que no hay cambios, pero la mayoría de los motores generarán códigos de operación para la doble negación. - Creciente Fresco

¿Pero cuál es el punto? Si lo hago if(0){... Javascript ya sabe que esto es falso. ¿Por qué es mejor decir if(!!0){...? - CodyBugstein

el punto es para las variables que quizás no conozca su contenido; si puede ser un número entero o una cadena, un objeto o nulo, indefinido, etc. Esta es una manera fácil de probar la existencia. - mezclar3d

!!foo aplica el operador unario no dos veces y se usa para convertir a un tipo booleano similar al uso de unario más +foo para lanzar un número y concatenar una cadena vacía ''+foo para lanzar a la cuerda.

En lugar de estos trucos, también puede utilizar las funciones de constructor correspondientes a los tipos primitivos (sin usar new) para emitir valores explícitamente, es decir

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo

Respondido el 10 de Septiembre de 09 a las 22:09

Pero luego puede tener problemas con instanceof. nueva instancia booleana (1) de objeto -> verdadero !! 1 instancia de objeto -> falso - Seamus

no, no puede: observe que las funciones constructoras se llaman sin new - como se menciona explícitamente en mi respuesta - Christoph

¡fantástico! Esto es útil para un pequeño truco cuando necesita evaluar cadenas con "0" como falso en lugar de verdadero. (es decir, al leer valores de selects, porque se leen como String). Entonces, si desea considerar "0" como negativo (booleano falso), asumiendo x="0" solo haz: x=!!+x; //false que es lo mismo que Boolean(Number(x)) Number (o + x) convierte la cadena "0" en 0, que SÍ se evalúa como falsa, y luego Boolean (!! x) la convierte directamente en boolean. ¡Pan comido! - DiegoDD

@DiegoDD, ¿por qué elegirías? !!+x vs x !== "0"? - placeyburdeos

@placeybordeaux porque, por ejemplo, es posible que desee convertir el valor y asignarlo a otra variable, independientemente de si lo va a comparar con otra cosa o no. - DiegoDD

Tantas respuestas haciendo la mitad del trabajo. Sí, !!X podría leerse como "la veracidad de X [representada como un booleano]". Pero !! prácticamente hablando, no es tan importante para determinar si una sola variable es (o incluso si muchas variables son) verdadera o falsa. !!myVar === true es lo mismo que solo myVar. Comparando !!X a un booleano "real" no es realmente útil.

Lo que ganas con !! es la capacidad de verificar la veracidad de múltiples variables unos contra otros de forma repetible, estandarizada (y compatible con JSLint).

Simplemente lanzando :(

Es decir...

  • 0 === false is false.
  • !!0 === false is true.

Lo anterior no es tan útil. if (!0) te da los mismos resultados que if (!!0 === false). No puedo pensar en un buen caso para convertir una variable en booleana y luego compararla con un booleano "verdadero".

Ver "== y! =" De Direcciones de JSLint (nota: Crockford está moviendo su sitio un poco; ese enlace puede morir en algún momento) para un poco sobre por qué:

Los operadores == y! = Escriben coerción antes de comparar. Esto es malo porque hace que '\ t \ r \ n' == 0 sea cierto. Esto puede enmascarar errores de tipo. JSLint no puede determinar de manera confiable si == se está usando correctamente, por lo que es mejor no usar == y! = En absoluto y siempre usar los operadores === y! == más confiables en su lugar.

Si solo le importa que un valor sea verdadero o falso, utilice la forma abreviada. En vez de
(foo != 0)

sólo decir
(foo)

y en lugar de
(foo == 0)

dices
(!foo)

Tenga en cuenta que hay algunos casos poco intuitivos donde un booleano se convertirá en un número (true es lanzado a 1 y false a 0) al comparar un booleano con un número. En este caso, !! podría ser útil mentalmente. Aunque, de nuevo, estos son casos en los que está comparando un booleano no booleano con un booleano de tipo rígido, lo cual es, en mi opinión, un error grave. if (-1) sigue siendo el camino a seguir aquí.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               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
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

Y las cosas se vuelven aún más locas dependiendo de su motor. WScript, por ejemplo, gana el premio.

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

Porque algunos jive históricos de Windows, eso dará como resultado -1 en un cuadro de mensaje! ¡Pruébelo en un indicador de cmd.exe y vea! Pero WScript.echo(-1 == test()) todavía le da 0, o WScript false. Apartar. Es espantoso.

Comparando la veracidad :)

Pero, ¿qué pasa si tengo dos valores que necesito para verificar la igualdad de veracidad / falsedad?

Fingir que tenemos myVar1 = 0; y myVar2 = undefined;.

  • myVar1 === myVar2 is 0 === undefined y es obviamente falso.
  • !!myVar1 === !!myVar2 is !!0 === !!undefined y es verdad! ¡Misma veracidad! (En este caso, ambos "tienen una veracidad de falsedad").

Entonces, el único lugar donde realmente necesitaría usar "variables de conversión booleana" sería si tuviera una situación en la que verificara si ambas variables tienen el mismo veracidad, ¿verdad? Es decir, utilizado !! si necesitas ver si dos vars son ambos verdaderos o ambos falsos (o no), es decir, de igual (o no) la verdad.

No puedo pensar en un gran caso de uso no artificial para eso. ¿Quizás tiene campos "vinculados" en un formulario?

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

Así que ahora si tienes una verdad para ambos or una falsedad para el nombre y la edad del cónyuge, puede continuar. De lo contrario, solo tiene un campo con un valor (o un matrimonio arreglado muy temprano) y necesita crear un error adicional en su errorObjects colección.


EDITAR 24 de octubre de 2017, 6 de febrero de 19:

Bibliotecas de terceros que esperan valores booleanos explícitos

He aquí un caso interesante ... !! puede ser útil cuando las bibliotecas de terceros esperan valores booleanos explícitos.

Por ejemplo, Falso en JSX (React) tiene un significado especial que no se desencadena por simple falsedad. Si intentó devolver algo como lo siguiente en su JSX, esperando un int en messageCount...

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

... te sorprenderá ver a React renderizar un 0 cuando tienes cero mensajes. Debe devolver explícitamente falso para que JSX no se procese. La declaración anterior vuelve 0, que JSX renderiza felizmente, como debería. No puedo decir que no tuviste Count: {messageCount && <div>Get your count to zero!</div>} (o algo menos artificial).

  • Una solución involucra el bangbang, que coacciona 0 dentro !!0, cual es false:
    {!!messageCount && <div>You have messages!</div>}

  • Los documentos de JSX sugieren que sea más explícito, escriba un código de comentarios propios y use una comparación para forzar a un booleano.
    {messageCount > 0 && <div>You have messages!</div>}

  • Me siento más cómodo manejando la falsedad yo mismo con un ternario.
    {messageCount ? <div>You have messages!</div> : false}

Lo mismo ocurre en TypeScript: si tiene una función que devuelve un valor booleano (o está asignando un valor a una variable booleana), [normalmente] no puede devolver / asignar un valor booleano-y; tiene que ser un booleano fuertemente tipado. Esto significa, si myObject está fuertemente tipado, return !myObject; funciona para una función que devuelve un booleano, pero return myObject; no lo hace. Tienes que return !!myObject para que coincida con las expectativas de Typecript.

¿La excepción para Typecript? Si myObject fue un any, estás de vuelta en el Salvaje Oeste de JavaScript y puedes devolverlo sin !!, incluso si su tipo de retorno es booleano.

Tenga en cuenta que estos son convenciones JSX y TypeScript, no los inherentes a JavaScript.

Pero si ves extraño 0s en su JSX renderizado, piense en una gestión de falsos sueltos.

Respondido el 20 de junio de 20 a las 10:06

Buena explicación. ¡¡Así que dirías el !! no es estrictamente necesario en este Detección de características del trabajador ¿ejemplo? if (!!window.Worker) - jk7

No, no lo necesitarías. Verdad y true "externamente" operan exactamente igual en un if. Sigo intentándolo, pero no puedo pensar en una razón para preferir convertir la veracidad en un valor booleano fuera del tipo de caso enrevesado de "comparar verdades", anterior, excepto por la legibilidad si reutiliza el valor más tarde, como en el q ejemplo de biblioteca. Pero incluso entonces, es un atajo que pierde información, y yo diría que es mejor evaluar la veracidad cada vez. - ruffin

Es solo el operador lógico NOT, dos veces: se usa para convertir algo a booleano, por ejemplo:

true === !!10

false === !!0

Respondido 24 Abr '09, 09:04

@Darren: No está comparando tipos; le está diciendo cuáles son los resultados, escribiendo afirmaciones en su respuesta. - Carreras de ligereza en órbita

Convierte el sufijo en un valor booleano.

Respondido 29 Oct 09, 21:10

Parece que el !! operador da como resultado una doble negación.

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true

respondido 09 nov., 11:10

Es un doble not operación. El primero ! convierte el valor en booleano e invierte su valor lógico. El segundo ! invierte el valor lógico.

Respondido el 10 de Septiembre de 09 a las 18:09

Simula el comportamiento del Boolean() función de fundición. El primero NOT devuelve un valor booleano independientemente del operando que se le proporcione. El segundo NOT niega que Boolean valor y así da el true Valor booleano de una variable. El resultado final es el mismo que usar el Boolean() función en un valor.

respondido 23 mar '11, 11:03

! es "booleano no", que esencialmente encasilla el valor de "habilitar" a su opuesto booleano. El segundo ! invierte este valor. Entonces, !!enable significa "no habilitar", lo que le da el valor de enable como booleano.

Respondido el 10 de Septiembre de 09 a las 18:09

!! está usando NOT operación dos veces juntas, ! convertir el valor a boolean y revertirlo, aquí hay un ejemplo simple para ver cómo !! obras:

Al principio, el lugar que tienes:

var zero = 0;

Entonces tu lo haces !0, se convertirá a booleano y se evaluará como true, porque 0 es falsy, por lo que obtiene el valor invertido y se convierte a booleano, por lo que se evalúa a true.

!zero; //true

pero no queremos lo inverso versión booleana del valor, por lo que podemos revertirlo nuevamente para obtener nuestro resultado. Por eso usamos otro !.

Básicamente, !! asegúrese de que el valor que obtenemos es booleano, no falso, verdadero o de cadena, etc.

Entonces es como usar Boolean función en javascript, pero una forma fácil y más corta de convertir un valor a booleano:

var zero = 0;
!!zero; //false

Respondido 08 Jul 19, 13:07

Creo que vale la pena mencionar que una condición combinada con un Y / O lógico no devolverá un valor booleano sino el último éxito o el primer error en el caso de && y el primer éxito o el último error en el caso de || de la cadena de condiciones.

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

Para convertir la condición en un verdadero literal booleano, podemos usar la doble negación:

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

contestado el 25 de mayo de 16 a las 11:05

No es un solo operador, son dos. Es equivalente a lo siguiente y es una forma rápida de convertir un valor en booleano.

val.enabled = !(!enable);

Respondido el 10 de Septiembre de 09 a las 22:09

La !! La construcción es una forma sencilla de convertir cualquier expresión de JavaScript en su equivalente booleano.

Por ejemplo: !!"he shot me down" === true y !!0 === false.

Respondido el 10 de Septiembre de 15 a las 09:09

Muy cerca de la distinción importante. La clave es que 0 === false es falso y !!0 === false es verdad. - ruffin

Sospecho que esto es un remanente de C ++ donde la gente anula el! operador pero no el operador bool.

Entonces, para obtener una respuesta negativa (o positiva) en ese caso, primero necesitaría usar el! operador para obtener un booleano, pero si quisiera marcar el caso positivo, usaría !!.

Respondido 24 Abr '09, 09:04

La if y while declaraciones y el ? El operador usa valores de verdad para determinar qué rama del código ejecutar. Por ejemplo, los números cero y NaN y la cadena vacía son falsos, pero otros números y cadenas son verdaderos. Los objetos son verdaderos, pero el valor indefinido y null son ambos falsos.

El operador de doble negación !! calcula el valor de verdad de un valor. En realidad, son dos operadores, donde !!x significa !(!x), y se comporta de la siguiente manera:

  • If x es un valor falso, !x is truey !!x is false.
  • If x es un verdadero valor, !x is falsey !!x is true.

Cuando se usa en el nivel superior de un contexto booleano (if, while o el ?), el !! El operador es conductualmente un no-op. Por ejemplo, if (x) y if (!!x) significa lo mismo.

Usos prácticos

Sin embargo, tiene varios usos prácticos.

Un uso es comprimir con pérdida un objeto a su valor de verdad, de modo que su código no contenga una referencia a un objeto grande y lo mantenga vivo. Asignar !!some_big_object a una variable en lugar de some_big_object déjalo para el recolector de basura. Esto es útil para los casos que producen un objeto o un valor falso como null o el valor indefinido, como la detección de funciones del navegador.

Otro uso, que mencioné en un respuesta sobre C correspondiente !! operador, es con herramientas de "pelusa" que buscan errores tipográficos comunes y diagnósticos de impresión. Por ejemplo, tanto en C como en JavaScript, algunos errores tipográficos comunes para las operaciones booleanas producen otros comportamientos cuya salida no es tan booleana:

  • if (a = b) es la asignación seguida por el uso del valor de verdad de b; if (a == b) es una comparación de igualdad.
  • if (a & b) es un AND bit a bit; if (a && b) es un AND lógico. 2 & 5 is 0 (un valor falso); 2 && 5 es verdad.

La !! El operador le asegura a la herramienta lint que lo que escribió es lo que quiso decir: realice esta operación, luego tome el valor de verdad del resultado.

Un tercer uso es producir XOR lógico y XNOR lógico. Tanto en C como en JavaScript, a && b realiza un AND lógico (verdadero si ambos lados son verdaderos), y a & b realiza un AND bit a bit. a || b realiza un OR lógico (verdadero si al menos uno es verdadero), y a | b realiza un OR bit a bit. Hay un XOR bit a bit (OR exclusivo) como a ^ b, pero no hay un operador incorporado para XOR lógico (verdadero si exactamente un lado es verdadero). Por ejemplo, es posible que desee permitir que el usuario ingrese texto en exactamente uno de dos campos. Lo que puede hacer es convertir cada uno a un valor de verdad y compararlos: !!x !== !!y.

respondido 06 mar '16, 14:03

Esta pregunta ha sido respondida bastante a fondo, pero me gustaría agregar una respuesta que espero sea lo más simplificada posible, ¡haciendo el significado de !! tan simple de entender como sea posible.

Debido a que javascript tiene lo que se llama valores "verdadero" y "falso", hay expresiones que, cuando se evalúan en otras expresiones, darán como resultado una condición de verdadero o falso, aunque el valor o la expresión que se esté examinando no sea realmente true or false.

Por ejemplo:

if (document.getElementById('myElement')) {
    // code block
}

Si ese elemento existe de hecho, la expresión se evaluará como verdadera y se ejecutará el bloque de código.

Sin embargo:

if (document.getElementById('myElement') == true) {
    // code block
}

... NO dará como resultado una condición verdadera y el bloque de código no se ejecutará, incluso si el elemento existe.

¿Por qué? Porque document.getElementById() es una expresión "veraz" que se evaluará como verdadera en este if() declaración, pero no es un valor booleano real de true.

El doble "no" en este caso es bastante simple. Son simplemente dos nots espalda con espalda.

El primero simplemente "invierte" el valor verdadero o falso, resultando en un tipo booleano real, y luego el segundo lo "invierte" nuevamente a su estado original, pero ahora en un valor booleano real. De esa manera tienes consistencia:

if (!!document.getElementById('myElement')) {}

y

if (!!document.getElementById('myElement') == true) {}

AMBOS devolverán verdadero, como se esperaba.

respondido 10 mar '19, 18:03

Negación booleana doble. A menudo se utiliza para comprobar si el valor no está indefinido.

Respondido el 02 de diciembre de 10 a las 20:12

!!x es taquigrafía para Boolean(x)

La primera explosión obliga al motor js a funcionar. Boolean(x) pero también tiene el efecto secundario de invertir el valor. Entonces, el segundo estallido deshace el efecto secundario.

Respondido el 04 de diciembre de 15 a las 12:12

Obliga a todas las cosas a ser booleanas.

Por ejemplo:

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true

Respondido el 06 de Septiembre de 18 a las 03:09

Hay toneladas de excelentes respuestas aquí, pero si ha leído hasta aquí, esto me ayudó a 'entenderlo'. Abra la consola en Chrome (etc.) y comience a escribir:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

Naturalmente, todos estos son lo mismo que simplemente escribir !! someThing, pero los paréntesis agregados pueden ayudar a que sea más comprensible.

Respondido 24 Abr '14, 14:04

Solo quería agregar eso

if(variableThing){
  // do something
}

es el mismo que

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

Pero esto puede ser un problema cuando algo no está definido.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
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

El truco aquí es la cadena de &&s volverá el primer valor falso encuentra - y esto se puede alimentar a una instrucción if, etc. Entonces, si b.foo no está definido, devolverá undefined y se saltará el b.foo.bar declaración, y no obtenemos ningún error.

Lo anterior devuelve indefinido, pero si tiene una cadena vacía, falso, nulo, 0, indefinido, esos valores regresarán y tan pronto como los encontremos en la cadena: [] y {} son "veraces" y continuaremos por la llamada "cadena &&" hasta el siguiente valor a la derecha.

PS Otra forma de hacer lo mismo es (b || {}).foo, porque si b no está definido entonces b || {} se mostrarán {}, y accederá a un valor en un objeto vacío (sin error) en lugar de intentar acceder a un valor dentro de "indefinido" (causa un error). Entonces, (b || {}).foo es el mismo que b && b.foo y ((b || {}).foo || {}).bar es el mismo que b && b.foo && b.foo.bar.

Respondido el 25 de junio de 19 a las 19:06

buen punto - cambié mi respuesta. Solo ocurre en un objeto cuando está anidado a tres niveles de profundidad, porque como dijiste ({}).anything daré undefined - Ryan Taylor

Después de ver todas estas excelentes respuestas, me gustaría agregar otra razón para usar !!. Actualmente estoy trabajando en Angular 2-4 (TypeScript) y quiero devolver un booleano como false cuando mi usuario no está autenticado. Si no está autenticado, la cadena de token sería null or "". Puedo hacer esto usando el siguiente bloque de código:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

respondido 29 mar '17, 08:03

aquí hay un fragmento de código de angular js

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

 var rafSupported = !!requestAnimationFrame;

su intención es establecer rafSupported en verdadero o falso según la disponibilidad de la función en requestAnimationFrame

se puede lograr comprobando de la siguiente manera en general:

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

el camino corto podría estar usando !!

rafSupported = !!requestAnimationFrame ;

así que si a requestAnimationFrame se le asignó una función, entonces! requestAnimationFrame sería falso y uno más! de eso sería verdad

si requestAnimationFrame se asignó como indefinido, entonces! requestAnimationFrame sería verdadero y uno más! de eso sería falso

respondido 04 mar '15, 08:03

Devuelve el valor booleano de una variable.

En su lugar, Boolean se puede utilizar la clase.

(lea las descripciones de los códigos)

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`

A saber, Boolean(X) = !!X en uso.

Verifique el fragmento de código a continuación

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

Respondido 11 Jul 17, 08:07

Upvoted .. En realidad iba a responder con esto si no está aquí ya. Usar el objeto booleano imo es un mejor enfoque desde el punto de vista de la legibilidad. Por ejemplo, no hay una pregunta "qué hace Boolean" SO con más de 3 votos a favor, como esta pregunta actual. - iPzard

Algunos operadores en JavaScript realizan conversiones de tipos implícitas y, a veces, se utilizan para la conversión de tipos.

El unario ! El operador convierte su operando en un booleano y lo niega.

Este hecho lleva a la siguiente expresión idiomática que puede ver en su código fuente:

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

Respondido 01 Jul 15, 08:07

Use el operador lógico no dos veces
significa !true = false y !!true = true

Respondido el 28 de diciembre de 20 a las 18:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.