5

I am looking through some code that someone else have written and I noticed this strange javascript if syntax.. Basicly, it looks like this:

// This is understandable (but I dont know if it have relevance)
var re = new RegExp("^" + someVar + "_", "i");

// !!~ ??? What is this black magic?
if (!!~varA.search(re)) { ... }

This is one of those things that is hard to google.. Any Javascript gurues that can explain this?

xeor
  • 5,301
  • 5
  • 36
  • 59
  • 1
    possible duplicate of [What is the !! (not not) operator in JavaScript?](http://stackoverflow.com/questions/784929/what-is-the-not-not-operator-in-javascript) – Matías Fidemraizer Sep 02 '13 at 13:08
  • 1
    possible duplicate of [Double exclamation points?](http://stackoverflow.com/questions/9284664/double-exclamation-points) – Quentin Sep 02 '13 at 13:09
  • 1
    And also check this http://www.javascriptturnsmeon.com/the-tilde-operator-in-javascript/ – Dmitry Kudryavtsev Sep 02 '13 at 13:10
  • 1
    As for what it is... it's a pointless syntax that saves 0 characters when typing and lowers legibility. `varA.search(re)>-1` is it's 'brother' – MDEV Sep 02 '13 at 13:14
  • I don't believe that this is a duplicate of other double-exclamation questions. `!!~` is quite different from `!!`. I'll admit, `!!~` is new to me. It is cryptic and I think it warrants its own question. I'd always prefer a much more expressive approach: `if(varA.search(re) >= 0)`. – Brian Genisio Sep 02 '13 at 13:16

3 Answers3

11

Unary operators like that just need to be interpreted from right to left. ~ is the bitwise "not" operator, and ! is the boolean inverse. Thus, those three:

  • convert the return value to an integer
  • invert the bits of the integer
  • inspect the number for "truthiness" (zero or non-zero, false or true)
  • invert the boolean value
  • invert it again

The ~ here is the trickiest. The "search" routine (I surmise) returns -1 when it doesn't find anything. The ~ operator turns -1 to 0, so the ~ allows one to interpret the "search" return value as true (non-zero) if the target is found, and false (zero) if not.

The subsequent application of ! — twice — forces the result to be a true boolean value. It's applied twice so that the true/false sense is maintained. edit Note that the forced conversion to boolean is not at all necessary in this particular code; the normal semantics of the if statement would work fine with just the result of the ~ operator.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • For reference, the `!!` is entirely unnecessary here. You'd only need it if you were storing the result for later and wanted to be sure it was a boolean. For immediate use in an `if`, it's overkill. – cHao Sep 02 '13 at 13:17
  • @cHao yes, in *this* example it's not necessary. – Pointy Sep 02 '13 at 13:19
  • @cHao In fact you could go further and say that the `~` is overkill, as you can just add `+1` so the "no match" return value is falsy and the "match in first position" becomes truthy. – Niet the Dark Absol Sep 02 '13 at 13:44
  • @Kolink: You could. But then again, `"~x".length < "x+1".length`. :) – cHao Sep 02 '13 at 14:38
  • But I've never once used `~` for any legitimate purpose, and I'm sure most other programmers don't use it either. Okay if you're going for minimalist, but if you're encouraging readability... Heh. – Niet the Dark Absol Sep 02 '13 at 22:02
4

Basically, .search returns the position at which it finds the result, or -1 if it doesn't match. Normal people would just write:

if( varA.search(re) > -1)

But personally I'd just use:

if( varA.match(re))
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

In laymans terms

 ~ 

is doing -(N+1) and

!!

The first bang casts from the number to a Boolean, and the second undoes the logical not that was performed by the first bang.

Have a look at this website.
it has a few explanations

http://dreaminginjavascript.wordpress.com/2008/07/04/28/

Johan
  • 8,068
  • 1
  • 33
  • 46