What is the purpose of using ~ in JavaScript?
I am trying to read the source code of Zepto.js
. And there is a place in function matches
that I don't understand:
zepto.matches = function(element, selector) {
if (!selector || !element || element.nodeType !== 1) return false
var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector ||
element.oMatchesSelector || element.matchesSelector
if (matchesSelector) return matchesSelector.call(element, selector)
var match, parent = element.parentNode, temp = !parent
if (temp) (parent = tempParent).appendChild(element)
//Here is my question. This line used the `~`
match = ~zepto.qsa(parent, selector).indexOf(element)
temp && tempParent.removeChild(element)
return match
}
Function matches
is used for determines whether an element matches the selector provided. It should return a Boolean.
And the zepto.qsa()
is Zepto's CSS selector implementation which uses document.querySelectorAll
and some other optimizes.
So. What is the purpose of the ~
in the following code ?
match = ~zepto.qsa(parent, selector).indexOf(element)
I know that ~
means Bitwise NOT
.
And (by my own tests):
~ -1 === 0
~ 0 === -1
~ 1 === -2
But I still don't understand what this design is for.
Can someone explain?
It is using the bitwise NOT operator to invert the results of the indexOf() function.
I'm not familiar with zepto.js but I can make a guess as to what the code is doing. First it calls the zepto.qsa()
method and passes the parent object and the selector. This method must return an array because it then calls indexOf()
to get the index for the element (which I assume is the element being "matched").
The Array.indexOf()
method returns -1 if the element is not found in the collection. As you've already seen a bitwise NOT on -1 gives you zero, which is equivalent to false
. Any other value that could come out would be equivalent to true
.
More generally this means you can use a bitwise NOT on indexOf()
to get a boolean value indicating if the element searched for exists in the collection or not.
Well.. it's a bitwise NOT, so you can use it when working with bits.
As for practical applications when you normally don't find yourself working with bits, here's a little trick:
if (~arr.indexOf(val)) doStuff();
//instead of
if (arr.indexOf(val) > -1) doStuff();
--edit--
I realize I didn't see you ask for an explanation for using ~
with indexOf
. Simply put, ~-1
evaluates to 0
. When you are using an if statement, 0
is a false value. It's a shorthand way for writing arr.indexOf(val) > -1
.