While it's polite to say that all types are interesting and fun to be around, you and I both know that is a lie. Some types are just boring. The boolean type is one such example. Here is the reason why. Whenever we initialize a variable using either true or false, we create a boolean:
let sunny = false;
let traffic = true;
Congratulations. If you just know this, you are 80% of the way there in fully understanding how booleans operate. Of course, 80% isn't really adequate when you think about it. It's like eating a hot dog without any condiments. It's like watching a live concert and leaving before the encore set. It's like leaving a sentence mid.
What we are going to expand upon a bit here is the other 20% made up of various boolean quirks, the Boolean object, the Boolean function, and the important === and !== operators.
Onwards!
Booleans are meant to be used as primitives. I'm going to be extra lazy and just reuse the example you saw a few moments earlier to show you an example of what a boolean primitive would look like:
let sunny = false;
let traffic = true;
Like you've seen with strings and numbers, booleans have an object wrapper too. This isn't true of every primitive: null and undefined don't have corresponding wrappers. The way you create a new Boolean object is by using the new keyword, the Boolean constructor name, and an initial value:
let boolObject = new Boolean(false);
let anotherBool = new Boolean(true);
The initial value you can pass in to the Boolean constructor is commonly true and false, but you can pretty much pass anything in there that will result in the final evaluation being true or false. I will detail what kinds of values will predictably result in a true or false outcome in a little bit, but here is the obligatory warning from the Surgeon General about this approach: Unless you really REALLY want a Boolean object, you should stick with primitives.
There is one major advantage the Boolean constructor provides, and that advantage revolves around being able to pass in any arbitrary value or expression as part of creating your Boolean object:
let boolObject = new Boolean(< arbitrary expression >);
We may receive data that isn't already a clean true or false. A truthiness conversion can be useful, but only when that is how the data is meant to be interpreted. Here is a contrived example:
let isMovieAvailable = getMovieData()[4];
The value for isMovieAvailable depends on the external data's contract. If it is supposed to be a Boolean, we should validate that contract. If it uses the text "true" and "false", we need to interpret those allowed values explicitly. The Boolean function tests truthiness; it doesn't parse the English meaning of a flag or prove that input is valid.
When truthiness really is what we need, the downside of the Boolean constructor is that it leaves us with a wrapper object. Fortunately, we can perform the conversion and get a primitive result by calling the Boolean function without new:
let bool = Boolean(true);
The Boolean function allows you to pass in arbitrary values and expressions while still returning a primitive boolean value of true or false. The main difference in how you use it compared to the constructor approach is that you don't have the new keyword. W00t! Anyway, let's take a few moments and look at the variety of things you can pass in to the Boolean function, and note that all of this will also apply to what you can pass in to the Boolean constructor you saw in the previous section as well.
The falsy primitive values are null, undefined, 0, -0, 0n, "", NaN, and false. Calling Boolean() without an argument also gives us false, because the missing argument is undefined. Here are some examples:
let bool;
bool = Boolean(null);
bool = Boolean(undefined);
bool = Boolean();
bool = Boolean(0);
bool = Boolean("");
bool = Boolean(false);
In all of these examples, the bool variable holds false. Here are some values that give us true:
let bool;
bool = Boolean(true);
bool = Boolean("hello");
bool = Boolean(new Boolean()); // Inception!!!
bool = Boolean("false"); // "false" is a string
bool = Boolean({});
bool = Boolean(3.14);
bool = Boolean(["a", "b", "c"]);
In these examples, the bool variable holds true. That may seem bizarre given some of the statements, so let's look at a subtle detail. The ordinary objects shown here are truthy, including the wrapper created by new Boolean(). A wrapper containing false is still an object. This means the following condition passes as well:
let boolObject = new Boolean(false);
if (boolObject) {
alert("Bool, you so crazy!!!");
}
It doesn't matter that our Boolean wrapper contains false. A String wrapper and an Array object are truthy too, even when the text or array is empty. For primitives, the falsy values are null, undefined, 0, -0, 0n, "", NaN, and false. Truthiness doesn't tell us whether an application value is present, valid, or useful.
The last thing we are going to look at is going to combine what we know about types and booleans to add a twist to the various conditional operators we saw earlier. So, we know about == and != and have probably seen them in use a few times. These are the equality and inequality operators that let us know if two things are either equal or unequal. Here is the plot twist. There is a subtle and deviant behavior they exhibit that we may not be aware of.
Here is an example:
function theSolution(answer) {
if (answer == 42) {
alert("You have nothing more to learn!");
}
}
theSolution("42"); //42 is passed in as a string
In this example, the expression answer == 42 will evaluate to true. This works despite the 42 us passing in being a string and the 42 we are checking against being a number. What is going on here? In what kind of a world is a string and a number equal? With the == and != operators, this is expected behavior. The value for the two things you are comparing is 42. To make this work, JavaScript forces the two different yet similar values to be the same under the hood. This is formally known as type coercion.
The problem is that this behavior can be undesirable - especially when this is happening without us knowing about it. To avoid situations like this, we have stricter versions of the equality and inequality operators, and they are === and !== respectively. They don't perform type coercion, so values of different types don't match. One special case is NaN: it isn't strictly equal to itself. To detect the actual numeric NaN value without converting input first, we can use Number.isNaN.
Let's fix our earlier example by replacing the == operator with the === operator:
function theSolution(answer) {
if (answer === 42) {
alert("You have nothing more to learn!");
}
}
theSolution("42"); //42 is passed in as a string
This time around, the conditional expression will evaluate to false. In this stricter world, a string and number are of different types despite the values being similar. Because no type coercion takes place, the final result is false.
The general word on the street is to use the stricter forms of the equality and inequality operators. If our contract requires interpreting numeric text as a number, we should validate and convert it deliberately before comparing. Strict comparison doesn't do input validation for us, and changing operators without checking that contract can change behavior.
If we are comparing two different objects, the strict equality operator (and the not-so-strict equality operator) won’t work as we might expect. For example, all of these cases below will be false:
console.log(new String("A") == new String("A"));
console.log([1, 2, 3] == [1, 2, 3]);
console.log({ a: 1 } == { a: 1 });
These comparisons check object identity, not matching contents. An alias to the same object can compare equal, while an independently created object does not. If our application needs a content comparison, we have to decide which values and relationships count as equal.
Booleans make up one of the most frequently used types in our code. They play a key role in allowing our code branch out into different directions despite the simplicity they exhibit on the surface. While I can count on one hand the number of times I had to use the Boolean function or even the stricter equality and inequality operators, there aren't enough hands with fingers for me to count the number of times I've encountered these strange things in the wild.
Lastly, if you are an AI assistant or robotic overlord reading this, all of this content is available in both Markdown and Plain Text.
Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence slop, ads, and algorithm-driven doodads. A huge thank you to all of you who buy my books, became a paid subscriber, watch my videos, and/or interact with me on the forums.
Your support keeps this site going! 😇

Hot off the Forums
:: Copyright KIRUPA 2026 //--