Converting to boolean using !!
operator
What is a boolean Value?
JavaScript has a Boolean data type. It can only take the values true or false, like YES/NO or ON/OFF
But, what is true and what is false?
JavaScript is very flexible about the types of values it requires. If JavaScript wants a boolean, it will convert whatever value you give it to a boolean.
Some values (“truthy” values) convert to true and others (“falsy” values) convert to false.
❎ False
false; // false
0 - // false
0; // false
0n; // false
(""); // false
null; // false
undefined; // false
NaN; // false
✅ True
true // true
42 // true
-13.3 // true
Infinity // true
-Infinity // true
{} // true ❗
[] // true ❗
"false" // true ❗
"0" // true ❗
" " // true ❗
...
Then, What !! is for?
A single “!” symbol in Javascript, also called a “bang”, is the logical “not” operator. If you place this operator in front of a value, it will converse it to boolean and reverse the value, returning the opposite. So, running a bang twice determines the opposite of value, and then returns the opposite of that.
(So !!
is not an operator, is just the !
operator used twice)
!!0; // return false
!!42; // return true
!!parseInt("foo"); // return false, NaN is falsy
!!window.foo; // return false, undefined is falsy
!!""; // return false
An example please
Sometimes you need to check whether the value of a variable exists and whether it is valid, so that in these cases we consider them true.
function BankAccount(cash) {
this.cash = cash;
this.hasMoney = !!cash;
}
let account = new BankAccount(100.5);
console.log(account.cash); // 100.50
console.log(account.hasMoney); // true
let emptyAccount = new BankAccount(0);
console.log(emptyAccount.cash); // 0
console.log(emptyAccount.hasMoney); // false
Combination with && operator
When you use &&
operator, if the first object is falsy, it returns that object
false && "dog";
// ↪ false
0 && "dog";
// ↪ 0
!!0 && "dog";
// ↪ false
A real life example please
!!
Might be useful when libraries expect explicit Boolean values, for instance React ⚛️
{
jobs.length && jobs.map((job) => <CardJob job={job} />);
}
{
jobs.length === 0 && <h1>No jobs to show</h1>;
}
⚠️ if jobs.length = 0, it will return 0, so te correct way is:
{
!!jobs.length && jobs.map((job) => <CardJob job={job} />);
}
{
jobs.length === 0 && <h1>No jobs to show</h1>;
}
You also probably used foo > 0
or foo != ""
for the same cases
And what about boolean()?
The result is the same, but according to this test looks like !! is faster than boolean() Test !! vs boolean()
⛔ Never use object new boolean()
Do not create Boolean objects. It slows down execution speed. The new keyword complicates the code. This produce unexpected results