!!
is used to convert a "truthy" or "falsey" value into true
or false
, and is equivalent to Boolean()
. For example
!!0 // false
!!1 // true
function Obj() {}
o = new Obj()
!!o // true
!!'' // false
!!'hi' // true
(1 && 3 && 4) // 4
!!(1 && 3 && 4) // true
!!x
can be read out loud as 'not not x'. The first !
turns a truthy value to false
and a falsey value to true
. Then the second !
reverses this so that the truthy value becomes true
and the falsey value becomes false
.
As to why people use that rather than Boolean
, this appears to be just a convention. It is concise and easily understood by most programmers, and there is possibly some resemblance to how people do things in C or C++. It is not particularly faster.
EDIT. You want to know why it is not redundant in this particular case. We may have no idea what type of object is being passed to the function as node
. &&
in javascript works from left to right and if all of the operands are truthy, returns the right-most operand, rather than true or false. Try redefining isElement
without the !!
. We get the following responses:
isElement('hi') // undefined
isElement(0) // 0
isElement(3) // undefined
isElement({nodeName: 'something'}) // 'something'
isElement({prop: 100, attr: this, find: Infinity}) // Infinity
These results will in fact be handled well most of the time -- in any if
statement the truthy values ('something', Infinity) will be treated as true and the falsey values (undefined, 0) treated as false. But still, the user of the API will expect it to return only true
or false
and there will occasionally be unexpected behaviours if it is allowed to return any of these things.