¿Qué hace una tilde cuando precede a una expresión?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Lo vi en una respuesta y nunca lo había visto antes.
¿Qué significa?
~
es un operador bit a bit que invierte todos los bits de su operando.
Por ejemplo, si su número fuera 1
, su representación binaria del flotante IEEE 754 (cómo JavaScript trata los números) sería...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Entonces ~
convierte su operando a un entero de 32 bits (los operadores bit a bit en JavaScript hacen eso)...
0000 0000 0000 0000 0000 0000 0000 0001
Si fuera un número negativo, se almacenaría en complemento a 2: se invierten todos los bits y se suma 1.
...y luego voltea todos sus bits...
1111 1111 1111 1111 1111 1111 1111 1110
Entonces, ¿de qué sirve? ¿Cuándo se podría utilizar alguna vez?
Tiene bastantes usos. Si estás escribiendo cosas de bajo nivel, es útil. Si perfiló su aplicación y encontró un cuello de botella, podría mejorar su rendimiento mediante el uso de trucos bit a bit (como una posible herramienta en una bolsa mucho más grande).
También es un truco (generalmente) poco claro convertir indexOf()
el valor de retorno encontrado en verdadero (mientras no se encuentra como falso ) y la gente a menudo lo usa por su efecto secundario de truncar números a 32 bits (y eliminar su decimal duplicándolo, efectivamente lo mismo que Math.floor()
para los números positivos).
Digo poco claro porque no es inmediatamente obvio para qué se utiliza. Generalmente, desea que su código se comunique claramente con otras personas que lo lean. Si bien su uso ~
puede parecer interesante , generalmente es demasiado inteligente para su propio bien. :)
También es menos relevante ahora que JavaScript tiene Array.prototype.includes()
y String.prototype.includes()
. Estos devuelven un valor booleano. Si su plataforma de destino lo admite, debería preferir esto para probar la existencia de un valor en una cadena o matriz.
Usarlo antes de una indexOf()
expresión efectivamente le brinda un resultado verdadero/falso en lugar del índice numérico que se devuelve directamente.
Si el valor de retorno es -1
, entonces ~-1
se 0
debe a que -1
es una cadena de 1 bits. Cualquier valor mayor o igual a cero dará un resultado distinto de cero. De este modo,
if (~someString.indexOf(something)) {
}
hará que el if
código se ejecute cuando "algo" esté en "alguna cadena". Si intenta utilizarlo .indexOf()
como booleano directamente, no funcionará porque a veces devuelve cero (cuando "algo" está al principio de la cadena).
Por supuesto, esto también funciona:
if (someString.indexOf(something) >= 0) {
}
y es considerablemente menos misterioso.
A veces también verás esto:
var i = ~~something;
Usar el ~
operador dos veces así es una forma rápida de convertir una cadena en un entero de 32 bits. El primero ~
realiza la conversión y el segundo ~
invierte los bits. Por supuesto, si el operador se aplica a algo que no se puede convertir en un número, se obtiene NaN
un resultado. ( editar : en realidad, es el segundo ~
el que se aplica primero, pero ya entiendes la idea).
El operador NOT bit a bit es ~
más o menos lo mismo que . Es más fácil de entender, más o menos. Entonces:~x
-(x+1)
~2; // -(2+1) ==> -3
Considerar -(x+1)
. -1
puede realizar esa operación para producir un 0
.
En otras palabras, ~
si se usa con un rango de valores numéricos, se producirá un valor falso (forzado a partir false
de 0
) solo para el -1
valor de entrada; de lo contrario, cualquier otro valor verdadero.
Como sabemos, -1
comúnmente se le llama valor centinela . Se utiliza para muchas funciones que devuelven >= 0
valores de éxito y fracaso -1
en lenguaje C. Que es la misma regla de valor de retorno en JavaScript.indexOf()
Es común comprobar la presencia/ausencia de una subcadena en otra cadena de esta manera
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
Sin embargo, sería más fácil hacerlo ~
como se muestra a continuación.
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
No conoces JS: tipos y gramática por Kyle Simpson
~indexOf(item)
aparece con bastante frecuencia, y las respuestas aquí son excelentes, pero tal vez algunas personas simplemente necesiten saber cómo usarlo y "saltarse" la teoría:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}