5

Can someone please explain the purpose of double-negating the reverse var in the below code?

return function (a,b) {
   var A = key(a), B = key(b);
   return ((A < B) ? -1 :
           (A > B) ? +1 : 0)) * [-1,1][+!!reverse];                  
}

The way I understand it, the purpose is to pick the proper index from the [-1,1] array to then use it in the multiplication but it seems to me that [-1,1][+!!reverse]; could be safely replaced by [-1,1][+reverse];

Am I wrong? What do you gain or prevent by double-negating reverse there?

I saw the above code on this answer.

Community
  • 1
  • 1
Icarus
  • 60,193
  • 14
  • 91
  • 110
  • That is awesome, curious to see an answer on this one – Dave Thomas Mar 30 '12 at 20:23
  • It changes the value of reverse to a boolean. [What is the !! (not not) operator in JavaScript?](http://stackoverflow.com/questions/784929/what-is-the-not-not-operator-in-javascript) – Mizuho Mar 30 '12 at 20:27
  • 1
    I would use `(reverse? 1 : -1)` instead of `[-1,1][+!!reverse]`, IMO is just more clear, it's cheaper, it doesn't need an array object and accessing an index, and even the boolean conversion is implicitly made by the conditional operator... – Christian C. Salvadó Mar 31 '12 at 04:56
  • @CMS I agree, if the whole purpose is just to multiply by 1 when true; otherwise by -1, `reverse?1:-1` is clearer and cheaper. – Icarus Mar 31 '12 at 05:06

4 Answers4

5

The easiest answer is probably a counter-example:

+undefined //NaN
+!!undefined // 0

since contents of [] are generally converted to strings, [NaN] will attempt to access the property called "NaN" from the array, which does not exist and will return undefined:

[1,-1][+undefined]
[1,-1][NaN]
[1,-1]["NaN"]
undefined
Dennis
  • 30,518
  • 9
  • 59
  • 75
4

Double negating simply ensures that we have a proper boolean. Since reverse could be anything, double negating it invokes JavaScript's "falsy" conversions. So, for example:

!!"hello" // true
!!"" // false
!!1 // true
!!some_undefined_var // false
bhamlin
  • 5,029
  • 1
  • 20
  • 17
2

The !! converts the value to a boolean. This is needed if reverse isn't a boolean to start off with.

Consider: +!!"hi". This is 1, but +"hi" is NaN.

Rocket Hazmat
  • 204,503
  • 39
  • 283
  • 323
1

the double-negation basically casts reverse as a boolean, and then + will cast that boolean as an int.

so, if reverse is possibly: "yes", "no", "", true, false, 0,1,2, undefined

the double negation will make "yes" -> true "no" -> true "" -> false true -> true false -> false undefined -> false

then, the + will convert trues to 1, and falses to 0, so that it can be used as an array index.

YenTheFirst
  • 2,022
  • 13
  • 11