tipos - Cuál es el !! ¿Operador(no) en JavaScript?
operadores javascript w3schools (30)
! es "boolean not", que esencialmente tipifica el valor de "enable" para su booleano opuesto. El segundo ! cambia este valor. Entonces !!enable
significa "no no habilitar", que le da el valor de enable
como booleano.
Vi un código que parece utilizar un operador que no reconozco, en forma de dos signos de exclamación, como por ejemplo: !!
. ¿Puede alguien decirme qué hace este operador?
El contexto en el que vi esto fue,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
Algunos operadores en JavaScript realizan conversiones de tipo implícitas, y algunas veces se usan para la conversión de tipo.
¡El unario !
el operador convierte su operando en un booleano y lo niega.
Este hecho lleva al siguiente idioma que puede ver en su código fuente:
!!x // Same as Boolean(x). Note double exclamation mark
Aquí hay un montón de respuestas geniales, pero si has 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 algo, algo, pero los paréntesis agregados pueden ayudar a hacerlo más comprensible.
Aquí hay un trozo de código de angular js
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame ||
$window.mozRequestAnimationFrame;
var rafSupported = !!requestAnimationFrame;
su intención es establecer rafSupported en true o false 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 se le asignara una función a requestAnimationFrame, entonces! requestAnimationFrame sería falso y uno más! de eso seria verdad
¡si requestAnimationFrame fue evaluado indefinidamente, entonces! requestAnimationFrame sería verdadero y uno más! de eso seria falso
Convierte el sufijo a un valor booleano.
Creo que vale la pena mencionar que una condición combinada con AND / OR lógico no devolverá un valor booleano, pero el último éxito o el primer error en caso de && y el primer éxito o el último error en caso de || de la cadena de la condición.
res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = (''foo'' || alert) // res is ''foo''
Para convertir la condición a 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
Devuelve el valor booleano de una variable.
En su lugar, se puede utilizar la clase Boolean
.
(por favor 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.
Por favor, consulte 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
Doble negación booleana. A menudo se utiliza para comprobar si el valor no está indefinido.
El !!
construir 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
.
Es solo el operador lógico NO, dos veces: se utiliza para convertir algo a booleano, por ejemplo:
true === !!10
false === !!0
Es una doble not
operación. El primero convierte el valor a booleano e invierte su valor lógico. El segundo invierte el valor lógico de nuevo.
Es una forma horriblemente oscura de hacer una conversión de tipos.
!
no es Entonces !true
es false
, y lo !false
es true
. !0
es true
, y !1
es false
.
Así que estás convirtiendo un valor en un booleano, luego lo inviertes y luego lo inviertes de nuevo.
// Maximum Obscurity:
val.enabled = !!userId;
// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;
// And finally, much easier to understand:
val.enabled = (userId != 0);
Las declaraciones if
y while
y el ?
el operador usa valores de verdad para determinar qué rama de 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 el valor null
son 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:
- Si
x
es un valor falso,!!x
estrue
, y!!x
esfalse
. - Si
x
es un valor verdadero,!!x
esfalse
, y!!x
estrue
.
Cuando se usa en el nivel superior de un contexto booleano ( if
, while
, o ?
), El !!
El operador es conductualmente un no-op. Por ejemplo, if (x)
y if (!!x)
significan 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, para 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
deja para el recolector de basura. Esto es útil para los casos que producen un objeto o un valor falso, como null
o el valor no definido, como la detección de características del navegador.
Otro uso, que mencioné en una respuesta sobre los correspondientes de C !!
operador , tiene 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 operaciones booleanas producen otros comportamientos cuyo resultado no es tan booleano:
-
if (a = b)
es una asignación seguida por el uso del valor de verdad deb
;if (a == b)
es una comparación de igualdad. -
if (a & b)
es un bit a AND;if (a && b)
es un AND lógico.2 & 5
es0
(un valor falso);2 && 5
es cierto.
El !!
el operador confirma a la herramienta de pelusa que lo que escribiste es lo que querías decir: haz esta operación, luego toma 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 a nivel de bits. a || b
a || b
realiza un OR lógico (verdadero si al menos uno es verdadero), y a | b
a | b
realiza un OR bit a bit. Hay un XOR bitwise (OR exclusivo) como a ^ b
, pero no hay un operador integrado para el XOR lógico (verdadero si un lado es verdadero). Podría, por ejemplo, desear permitir que el usuario ingrese texto en exactamente uno de los dos campos. Lo que puedes hacer es convertir cada uno a un valor de verdad y compararlos: !!x !== !!y
.
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);
Obligaciones oObject
al booleano. Si fue falsey (por ejemplo, 0, null
, undefined
, etc.), será false
, de lo contrario, true
.
!oObject //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation
Entonces !!
no es un operador, es solo el !
Operador dos veces.
Ejemplo del mundo real "Versión de prueba de IE":
let isIE8 = false;
isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // returns true or false
Si usted ⇒
console.log(navigator.userAgent.match(/MSIE 8.0/));
// returns null
pero si ⇒
console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// returns true or false
Parece que el !!
El operador da como resultado una doble negación.
var foo = "Hello World!";
!foo // Result: false
!!foo // Result: true
Simula el comportamiento de la función de conversión Boolean()
. El primer NOT
devuelve un valor booleano sin importar qué operando se le dé. El segundo NOT
niega ese valor Boolean
y, por lo tanto, da el true
valor booleano de una variable. El resultado final es el mismo que usar la Boolean()
en un valor.
Solo queria agregar eso
if(variableThing){
// do something
}
es lo mismo que
if(!!variableThing){
// do something
}
Pero esto puede ser un problema cuando algo no está definido.
// 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
El truco aquí es que la cadena de &&
s devolverá el primer valor falsey que encuentre, y esto se puede enviar a una sentencia if, etc. Por lo tanto, si b.foo no está definido, se devolverá indefinido y se omitirá b.foo.bar
Declaración, y no obtenemos ningún error.
El retorno por encima indefinido pero si usted tiene una cadena vacía, falsa, NULL, 0, sin definir esos valores y volverán pronto como los encontramos en la cadena - []
y {}
los dos estamos Truthy.
Sospecho que esto es un resto de C ++ donde las personas anulan el! operador pero no el operador bool.
Entonces, para obtener una respuesta negativa (o positiva) en ese caso, ¡primero necesitarías usar el! operador para obtener un booleano, pero si desea comprobar el caso positivo utilizaría !!.
Tantas respuestas haciendo la mitad del trabajo. Sí, !!X
podría leerse como "la veracidad de X [representada como un booleano]". Pero !!
no es, en la práctica, tan importante para determinar si una sola variable es (o incluso si muchas variables son) veraz o falsa. !!myVar === true
es lo mismo que solo myVar
. Comparar !!X
con un booleano "real" no es realmente útil.
Lo que ganas con !!
es la capacidad de verificar la veracidad de múltiples variables entre sí de manera repetible y estandarizada (y compatible con JSLint).
Simplemente casting :(
Es decir...
-
0 === false
esfalse
-
!!0 === false
estrue
.
Lo de arriba no es tan útil. if (!0)
le da los mismos resultados que if (!!0 === false)
. No puedo pensar en un buen caso para convertir una variable en booleano y luego compararlo con un booleano "verdadero".
Vea "== y! =" En las instrucciones de JSLint (nota: Crockford está moviendo su sitio un poco; ese enlace podría morir en algún momento) por un poco sobre por qué:
Los operadores == y! = Tipifican la coerción antes de comparar. Esto es malo porque hace que ''/ t / r / n'' == 0 sea verdadero. 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 usar siempre los operadores más confiables === y! == en su lugar.
Si solo te importa que un valor sea verdadero o falso, entonces usa la forma corta. En lugar de
(foo != 0)
sólo decir
(foo)
y en lugar de
(foo == 0)
decir
(!foo)
Tenga en cuenta que hay algunos casos no intuitivos en los que un valor booleano se convertirá en un número ( true
se convierte en 1
y false
en 0
) cuando se compara un valor booleano con un número. En este caso, !!
podría ser mentalmente útil. Aunque, nuevamente, estos son casos en los que estás comparando un booleano no booleano con un booleano duro, lo que es, imo, 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 ponen aún más locas dependiendo de tu motor. WScript, por ejemplo, gana el premio.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Debido a algún jive histórico 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())
aún le da 0, o WScript es false
. Apartar. Es horrible
Comparando la verdad :)
Pero ¿qué pasa si tengo dos valores que necesito para verificar la veracidad / falsedad?
Imagina que tenemos myVar1 = 0;
y myVar2 = undefined;
.
-
myVar1 === myVar2
es0 === undefined
y obviamente es falso. -
!!myVar1 === !!myVar2
es!!0 === !!undefined
y es cierto! La misma verdad! (En este caso, ambos "tienen una verdad falsa".)
Entonces, el único lugar en el que realmente necesitarías usar "variables de conversión booleana" sería si tuvieras una situación en la que verificas si ambas variables tienen la misma verdad, ¿verdad? Es decir, usar !!
si necesita ver si dos variables son verdaderas o falsas (o no), es decir, de la verdad (o no) igual .
No puedo pensar en un gran caso de uso no ideado para eso de antemano. Tal vez usted 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 tiene una verdad para ambos o una falsa para el nombre y la edad de su cónyuge, puede continuar. De lo contrario, solo tiene un campo con un valor (o un matrimonio concertado muy temprano) y necesita crear un error adicional en su colección errorObjects
.
EDITAR 24 oct 2017:
Bibliotecas de terceros que esperan valores booleanos explícitos
Aquí hay un caso interesante ... !!
podría ser útil cuando las bibliotecas de terceros esperan valores booleanos explícitos.
Por ejemplo, False in JSX (React) tiene un significado especial que no se activa con la falsedad simple. Si intentó devolver algo como lo siguiente en su JSX, esperando un int en messageCount
...
{messageCount && <div>You have messages!</div>}
... es posible que se sorprenda al ver que React genera un 0
cuando tiene cero mensajes. Tiene que devolver explícitamente false para que JSX no se genere. La declaración anterior devuelve 0
, que JSX presenta felizmente, como debería. No puedo decir que no tenía Count: {messageCount && <div>Get your count to zero!</div>}
(o algo menos ideado).
Una solución involucra el bangbang, que convierte a
0
en!!0
, que esfalse
:
{!!messageCount && <div>You have messages!</div>}
Los documentos de JSX sugieren que sea más explícito, escriba código de auto comentario 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 con un ternario.
{messageCount ? <div>You have messages!</div> : false}
Tenga en cuenta que esta es una convención JSX , no una inherente a JavaScript .
Pero si ve 0
s extraños en su JSX renderizado, piense en una gestión falsa.
Utilice el operador lógico no dos veces
significa! verdadero = falso
y !! verdadero = verdadero
!!
convierte el valor a su derecha en su valor booleano equivalente. (Piensa en la forma de "tipografía" del pobre hombre). Por lo general, su intención es transmitir al lector que al código no le importa qué valor tiene la variable, sino cuál es el valor de "verdad" .
!!
está usando la operación NOT
dos veces juntas !
convierta el valor a boolean
e inviértalo, aquí hay un ejemplo simple para ver cómo. trabajos:
Al principio, lugar tienes:
var zero = 0;
Luego lo hace !0
, se convertirá en booleano y se evaluará en true
, porque 0 es falsy
, por lo que obtiene el valor invertido y se convierte en booleano, por lo que se evalúa en true
.
!zero; //true
¡Pero no queremos la versión booleana invertida del valor, por lo que podemos revertirla nuevamente para obtener nuestro resultado! Es por eso que usamos otro !
.
Básicamente, !!
Asegúrese de que el valor que obtengamos sea booleano, no falso, sincero o de cadena, etc.
Así que es como usar Boolean
función Boolean
en javascript, pero una forma fácil y más corta de convertir un valor a booleano:
var zero = 0;
!!zero; //false
!!
es similar a usar el constructor booleano , o posiblemente más parecido a la función 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
Los valores de Falsey en javascript obligan a falso , y los valores de verdad coaccionan a verdadero. Los valores de Falsey y de veracidad también pueden usarse en if
declaraciones y esencialmente se "asignarán" a su valor booleano correspondiente. Sin embargo, es probable que no tenga que usar los valores booleanos adecuados a menudo, ya que en su mayoría difieren en la salida (valores de retorno).
Si bien esto puede parecer similar al lanzamiento, en realidad es probable que se trate de una mera coincidencia y no se "construya" o se haga a propósito como un modelo booleano. Así que no lo llamemos así.
¿Por qué y cómo funciona?
Para ser concisos, se ve algo como esto: ! ( !null )
. Considerando que, null
es falsey , así !null
sería verdad . Entonces !true
sería falso y, en esencia, se volvería a invertir en lo que era antes, excepto esta vez como un valor booleano adecuado (o incluso viceversa con valores de verdad como {}
o 1
).
Volviendo a tu ejemplo.
En general, el contexto que vio simplemente se ajusta this.vertical
dependiendo de si vertical
está definido o no , y si es así; se establecerá en el valor booleano de la vertical resultante, de lo contrario no cambiará. En otras palabras, si vertical
está definido; this.vertical
se establecerá en su valor booleano, de lo contrario, seguirá siendo el mismo. Supongo que en sí mismo es un ejemplo de cómo usarías !!
, y lo que hace.
Ejemplo de E / S vertical
Ejecute este ejemplo y juegue con el valor vertical en la entrada. Vea a qué obliga el resultado para que pueda comprender completamente el código de su contexto. En la entrada, ingrese cualquier valor válido de javascript. Recuerde incluir las citas si está probando una cadena. No te preocupes demasiado por el código CSS y HTML, simplemente ejecuta este fragmento y juega con él. Sin embargo, puede querer echar un vistazo al código javascript no relacionado con DOM (el uso del constructor de ejemplo y la variable 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
devuelve un valor booleano ( true
o false
) dependiendo de la veracidad de la expresión. Tiene más sentido cuando se usa en tipos no booleanos. Considere estos ejemplos, especialmente el tercer ejemplo y el siguiente:
!!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!
!!foo
aplica el operador unary no dos veces y se usa para convertir en un tipo booleano similar al uso de unary plus +foo
para convertir en número y concatenar una cadena vacía ''''+foo
para lanzar en una cadena.
En lugar de estos hacks, también puede usar las funciones del 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
!!x
es la abreviatura de Boolean(x)
La primera explosión obliga al motor js a ejecutar Boolean(x)
pero también tiene el efecto secundario de invertir el valor. Así que la segunda explosión deshace el efecto secundario.
Prepare 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 que
false
no estrue
(por eso!false
resultatrue
)La verdad es que lo
true
no esfalse
(por eso!true
resultafalse
)
!!
determina la "verdad" de lo que un valor no es:
La verdad es que la
true
no estrue
(!!true
por eso!!true
resulta entrue
)La verdad es que
false
no esfalse
(!!false
por eso!!false
resultafalse
)
Lo que deseamos determinar en la comparación es la "verdad" sobre el valor de una referencia, no el valor de la referencia en sí. Existe un caso de uso en el que podemos querer saber la verdad sobre un valor, incluso si esperamos que el valor sea false
(o falso), o si esperamos que el valor no sea de tipo boolean
.
En la práctica:
Considere una función concisa que detecte la funcionalidad de la característica (y en este caso, la compatibilidad de la plataforma) por medio de la escritura dinámica (también conocida como "tipografía de pato"). Queremos escribir una función que devuelva true
si el navegador de un usuario admite el elemento <audio>
HTML5, pero no queremos que la función arroje un error si <audio>
no está definido; y no queremos usar try ... catch
para manejar los posibles errores (porque son graves); y tampoco queremos usar una verificación dentro de la función que no revele constantemente la verdad sobre la característica (por ejemplo, document.createElement(''audio'')
aún creará un elemento llamado <audio>
incluso si HTML5 <audio>
no es compatible).
Aquí están 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 un attribute
para buscar, pero cada uno devuelve valores diferentes según lo que determinan las comparaciones.
¡Pero espera hay mas!
Algunos de ustedes probablemente se dieron cuenta de que en este ejemplo específico, uno podría simplemente verificar una propiedad utilizando los medios ligeramente más eficaces para verificar 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
Estamos divagando ...
Por muy raras que puedan ser estas situaciones, pueden existir algunos escenarios en los que el medio más conciso, más eficaz y, por lo tanto, el más preferido de ser true
partir de un valor no booleano, posiblemente no definido, ¡¡de hecho se usa !!
. Esperemos que esto lo aclare ridículamente.
Después de ver todas estas grandes respuestas, me gustaría agregar otra razón para usar !!
.En este momento 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
o ""
. Puedo hacer esto usando el siguiente bloque de código:
public isAuthenticated(): boolean {
return !!this.getToken();
}
a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined
Para !a
, verifica si a
NO está definido, mientras que !!a
comprueba si la variable está definida.
!!a
es lo mismo que !(!a)
. Si se define a, a
es true
, !a
es false
y !!a
es true
.