If you read the comments at the jQuery inArray
page here, there's an interesting declaration:
!!~jQuery.inArray(elm, arr)
Now, I believe a double-exclamation point will convert the result to type boolean
, with the value of true
. What I don't understand is what is the use of the tilde (~
) operator in all of this?
var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Refactoring the if
statement:
if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Breakdown:
jQuery.inArray("one", arr) // 0
~jQuery.inArray("one", arr) // -1 (why?)
!~jQuery.inArray("one", arr) // false
!!~jQuery.inArray("one", arr) // true
I also noticed that if I put the tilde in front, the result is -2
.
~!!~jQuery.inArray("one", arr) // -2
I don't understand the purpose of the tilde here. Can someone please explain it or point me towards a resource?
The
~
operator is the bitwise complement operator. The integer result frominArray()
is either -1, when the element is not found, or some non-negative integer. The bitwise complement of -1 (represented in binary as all 1 bits) is zero. The bitwise-complement of any non-negative integer is always non-zero.Thus,
!!~i
will betrue
when integer "i" is a non-negative integer, andfalse
when "i" is exactly -1.Note that
~
always coerces its operand to integer; that is, it forces non-integer floating point values to integer, as well as non-numeric values.There's a specfic reason you'll sometimes see
~
applied in front of$.inArray
.Basically,
is a shorter way to do
$.inArray
returns the index of the item in the array if the first argument is found, and it returns -1 if its not found. This means that if you're looking for a boolean of "is this value in the array?", you can't do a boolean comparison, since -1 is a truthy value, and when $.inArray returns 0 (a falsy value), it means its actually found in the first element of the array.Applying the
~
bitwise operator causes-1
to become0
, and causes 0 to become `-1. Thus, not finding the value in the array and applying the bitwise NOT results in a falsy value (0), and all other values will return non-0 numbers, and will represent a truthy result.And it'll work as intended.
!!~expr
evaluates tofalse
whenexpr
is-1
otherwisetrue
.It is same as
expr != -1
, only broken*It works because JavaScript bitwise operations convert the operands to 32-bit signed integers in two's complement format. Thus
!!~-1
is evaluated as follows:A value other than
-1
will have at least one bit set to zero; inverting it will create a truthy value; applying!
operator twice to a truthy value returns boolean true.When used with
.indexOf()
and we only want to check if result is-1
or not:*
!!~8589934591
evaluates to false so thisabominationcannot be reliably used to test for-1
.~foo.indexOf(bar)
is a common shorthand to representfoo.contains(bar)
because thecontains
function doesn't exist.Typically the cast to boolean is unnecessary due to JavaScript's concept of "falsy" values. In this case it's used to force the output of the function to be
true
orfalse
.jQuery.inArray()
returns-1
for "not found", whose complement (~
) is0
. Thus,~jQuery.inArray()
returns a falsy value (0
) for "not found", and a truthy value (a negative integer) for "found".!!
will then formalise the falsy/truthy into real booleanfalse
/true
. So,!!~jQuery.inArray()
will givetrue
for "found" andfalse
for "not found".Tilde is bitwise NOT - it inverts each bit of the value. As a general rule of thumb, if you use
~
on a number, its sign will be inverted, then 1 will be subtracted.Thus, when you do
~0
, you get -1 (0 inverted is -0, subtract 1 is -1).It's essentially an elaborate, super-micro-optimised way of getting a value that's always Boolean.