17

¿Para qué sirve el operador !!~?

Lo estoy usando en este código que encontré en GitHub:

function multifiltros(array, filters) {
  const filterKeys = Object.keys(filters);

  return array.filter((item) => {

    return filterKeys.every(key => !!~filters[key].indexOf(item[key]));
//                                 ^^^
//                                 aquí
  });
}
fedorqui
  • 15,850
  • 17
  • 58
  • 112
Angel
  • 497
  • 3
  • 10
  • 27

2 Answers2

17

No es un solo operador, es el uso conjunto de tres operadores ( dos ! y un ~).


Antes de entrar en detalle sobre que hace en el código, una explicación sobre cada operador:

! es la negación

La doble negación (!!) mayormente se usa para forzar la conversión del tipo a boolean, como por ejemplo:

var token_null = null;
console.log( 'token_null   =', token_null );   // null
console.log( '!token_null  =', !token_null );   // true
console.log( '!!token_null =', !!token_null );  // false

console.log( '-----------' );

var token_undefined = undefined;
console.log( 'token_undefined   =', token_undefined );   // undefined
console.log( '!token_undefined  =', !token_undefined );  // true
console.log( '!!token_undefined =', !!token_undefined ); // false

console.log( '-----------' );

var token_0 = 0;
console.log( 'token_0   =', token_0 );   // 0
console.log( '!token_0  =', !token_0 );  // true
console.log( '!!token_0 =', !!token_0 ); // false
    
console.log( '-----------' );

var token_string = 'mi_token';
console.log( 'token_string   =', token_string );   // "mi_token"
console.log( '!token_string  =', !token_string );  // false
console.log( '!!token_string =', !!token_string ); // true

Puedes ver mas información sobre la doble negación aquí mismo en SO


~ es NOT a nivel bit

Un ejemplo rápido:

console.log(~0); // Es igual a -1

console.log(~-1); // Es igual a 0;

console.log(~11); // Es igual a -12;

Puedes leer mas sobre el NOT a nivel bits aquí


¿Que hace ahí?

Ahora que terminamos la introducción, lo que hace !!~filters[key].indexOf(item[key]) es devolver false solamente en el caso que no se encuentra la key dentro del array filters.

¿Por que? Porque si no se encuentra el elemento, .indexOf() devuelve -1, al cual si le aplicamos ~ se convierte en 0, que equivale a false.

var noEncontrado = -1;
console.log(!!~noEncontrado);

Ahora bien, si sacas el !! es totalmente el mismo comportamiento debido a como funciona el .every() , como puedes ver aquí:

// -1 simula la situación en la que indexOf() no encuentre el elemento, el resto de los valores haría referencia a la posición del elemento

var prueba1 = [1,0,2,3,-1].every(a=>!!~a); // da false
console.log(prueba1);

var prueba2 = [1,0,2,3,-1].every(a=>~a); // da false
console.log(prueba2);

var prueba3 = [1,0,2,3,1].every(a=>!!~a); // da true
console.log(prueba3);

var prueba4 = [1,0,2,3,1].every(a=>~a); // da true
console.log(prueba4);
Federico Madoery
  • 2,858
  • 9
  • 19
1

En concreto !!~ no es un operador, sino que es un conjunto de varios operadores. Lo estoy viendo y no le encuentro mucha utilidad, pero si te sirve de algo. Te dejo explicado por separado los dos operadores que pude identificar.

Con el !! haces una doble negación lo que transforma un valor en Booleano.

!true = false
!!true = true

Y el simbolo ~ es el NOT logico que lo que hace es invertir los bits

~5(decimal) => ~0101(binario) => 1010(binario) => 10(decimal)

Mas info: https://www.w3schools.com/js/js_operators.asp

Saludos!

Alexander
  • 55
  • 4