What does "!!~" mean in Javascript?

Asked

Viewed 246 times

13

I am studying Javascript and came across the following code:

manageLag(selected) {
    if(!!~this.selections.indexOf(selected.url)) {
        selected.at += 5
        return;
    }

    this.selections.push(selected.url)
}

I couldn’t understand what the if is checking. What the !!~ is making?

2 answers

13


There are three operators working together, two of them being the logical negation operator (Logic NOT!) and the third, the operator bitwise of denial (bitwise NOT~).

In that case, the first operator to be rated will be the bitwise NOT. Use it in conjunction with the indexOf was a relatively common practice in Javascript. Let’s understand why.

In general, the bitwise NOT (~), when applied in numbers, it works as follows:

~N -> -(N + 1)

Thus, when we apply it in -1, we have:

~(-1) -> -(-1 + 1) -> -(0) -> 0

Some examples:

[-3, -2, -1, 0, 1, 2, 3].forEach((num) => {
  console.log('~' + num, '=', ~num);
});

Generally, we want to get a Boolean response (true or false) to know if an element is contained in a list (or string) or not. However, historically, Javascript only relied on the method indexOf to make that search that for some reason (probably to serve as error code), returns -1 if the element does not exist in the list.

Thus, a concise way to turn the return into a value Truthy or falsy is to use the operator ~. To -1, we shall have 0 (that is falsy) and, for any other number, we will have values Truthy.

Then we use the two operators !! to convert the result of ~ in, in fact, a boolean. This answer gives more details on this. Could also use the constructor Boolean, which is a more explicit (but less concise) way to do the same. Let’s see:

// Note que, para `0`, teremos `false`. Para qualquer
// valor numárico diferente de zero, teremos `true`.

[-2, -1, 0, 1, 2].forEach((num) => {
  console.log('!!' + num, '=', !!num);
  console.log(`Boolean(${num}) =`, Boolean(num));
});

In short, combining the double negation (!!) with the bitwise NOT, we guarantee that, for the result -1 of indexOf, we shall have false. For any other result of indexOf, the expression of operators will evaluate to true.


Currently, there are already methods that return a boolean value to check if a list contains an element. Some examples are:

Therefore, if you are in any environment that supports these new methods, the use of !!~ can be seen as unnecessary. It is certainly also less understandable for those who are starting to learn Javascript.

  • 3

    had begun to edit an answer but no longer need :D

  • 2

    Always punctual @Ricardopunctual.

  • @Wallacemaxters was really fast :D

9

The code in question may be divided into parts to facilitate understanding:

const stringVazia = "";
const num100 = 100;

console.log("!stringVazia:", !stringVazia);
console.log("!!stringVazia:", !!stringVazia);
console.log("stringVazia === !!stringVazia:", stringVazia === !!stringVazia);
console.log("~stringVazia:", ~stringVazia);
console.log("!~stringVazia:", !~stringVazia);
console.log("!!~stringVazia:", !!~stringVazia);

console.log('');

console.log("!num100:", !num100);
console.log("!!num100:", !!num100);
console.log("num100 === !!num100:", num100 === !!num100);
console.log("~num100:", ~num100);
console.log("!~num100:", !~num100);
console.log("!!~num100:", !!~num100);

  • 1

    Very good, but I confess I never even saw about it XD. I never got to see a code using it. In my view, this operator ~ works only with numbers, would that?

  • 1

    @Cmtecardeal depends on what you mean by "works". Yes, it is made for numbers. You can see in the specification of Ecmascript 2015: the given value and the returned value are converted to 32-bit integers, then a string ends up being NaN.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.