What does the double negation operator !! do in JavaScript?
By Flavio Copes
Learn what the double negation operator !! does in JavaScript: it is two negations that coerce any value into its boolean equivalent, true or false.
Suppose you have an expression, which gives you a result.
You want this result to be a boolean. Either true or false.
Not a string, 0, an empty string, undefined, NaN or whatever. true or false.
The !! operator does that.
And in reality it’s two negation operators one after the other. There’s no !! operator in JavaScript. But there’s !.
It first negates the result of the expression, then it negates it again. In this way if you had a non-zero number, a string, an object, an array, or anything that’s truthy, you’ll get true back.
Otherwise you’ll get false.
How it works, step by step
Take the string 'hello'. The first ! converts it to a boolean and negates it, so we get false. The second ! flips it back:
!'hello' //false
!!'hello' //true
Here it is applied to the falsy values:
!!0 //false
!!'' //false
!!null //false
!!undefined //false
!!NaN //false
And to some truthy ones:
!!1 //true
!!'hi' //true
!!{} //true
!![] //true
Notice the last two. An empty object and an empty array are both truthy. That surprises people coming from languages where an empty collection counts as false.
When would you use it?
A typical case is returning a clean boolean from a function, instead of leaking the value you were checking:
const hasDiscount = (user) => {
return !!user.discountCode
}
hasDiscount({ discountCode: 'SUMMER20' }) //true
hasDiscount({}) //false
Without the !!, the first call would return 'SUMMER20' and the second undefined. Both work fine inside an if, but if the function promises a boolean, let’s return one.
An alternative: Boolean()
Calling Boolean() as a function does the exact same conversion, and reads more explicitly:
Boolean('hello') //true
Boolean(0) //false
Pick the one you prefer, and stay consistent across your codebase.
A pitfall to know about
!! checks truthiness, not meaning. The string 'false' is a non-empty string, so it converts to true:
!!'false' //true
This bites you when the value comes from a query string or an environment variable, where everything arrives as a string. In that case, compare against the actual expected value:
const debug = process.env.DEBUG === 'true'Related posts about js: