What is the !! (Not Not) Operator in JavaScript? How It Works with Code Examples
JavaScript is known for its flexible (and sometimes confusing) type system, where values can be coerced into different types implicitly. Among its many operators, the !! (double negation, or "Not Not") operator stands out as a concise tool for explicitly converting values to their boolean equivalents. While it may look like a typo or a trick, !! is widely used in JavaScript codebases to check for "truthiness" or "falsiness" of values.
In this blog, we’ll demystify the !! operator: what it is, how it works under the hood, practical use cases, common examples, edge cases, and when to (or not to) use it. By the end, you’ll have a clear understanding of how to leverage !! effectively in your code.
Table of Contents#
- What is the
!!Operator? - How Does the
!!Operator Work? - Practical Use Cases for
!! - Common Examples with Code
- Edge Cases and Considerations
- When to Use (and When Not to Use)
!! - Conclusion
- References
What is the !! Operator?#
The !! operator is not a standalone JavaScript operator. Instead, it’s a combination of two consecutive logical NOT (!) operators. Its sole purpose is to convert any value into its boolean equivalent by leveraging JavaScript’s type coercion rules.
In short:
!!valuereturnstrueifvalueis "truthy" (i.e., coerces totruein a boolean context).!!valuereturnsfalseifvalueis "falsy" (i.e., coerces tofalsein a boolean context).
How Does the !! Operator Work?#
To understand !!, we first need to break down the single ! operator, as !! is just ! applied twice.
Step 1: The Single ! (Logical NOT) Operator#
The logical NOT (!) operator does two things:
- Converts the operand to a boolean.
- Negates (inverts) the result.
For example:
- If the operand is truthy,
!converts it totrue, then negates tofalse. - If the operand is falsy,
!converts it tofalse, then negates totrue.
JavaScript has 8 falsy values:
false, 0, -0, 0n (BigInt zero), "" (empty string), null, undefined, and NaN. All other values are truthy.
Step 2: Applying ! Twice (!!)#
The !! operator applies ! twice. Here’s the breakdown:
- First
!: Converts the value to a boolean and negates it (as above). - Second
!: Negates the result again, effectively undoing the first negation but leaving the boolean conversion intact.
Thus, !!value is equivalent to Boolean(value)—it explicitly converts value to its boolean counterpart.
Example: Let’s use value = "hello" (a truthy value):
- First
!:!"hello"→false(since "hello" is truthy,!converts totruethen negates tofalse). - Second
!:!false→true. - Result:
!!"hello" === true.
Practical Use Cases for !!#
Why use !! instead of relying on implicit coercion? Here are common scenarios:
1. Explicit Boolean Conversion#
When you need to ensure a variable is strictly a boolean (not just truthy/falsy) for clarity or type safety. For example, in state management or function parameters:
// Ensure `hasPermission` is a boolean, not a truthy/falsy value
const user = { permissions: ["read"] };
const hasPermission = !!user.permissions.includes("write"); // false (boolean)2. Checking for Value Presence#
Quickly determining if a value exists (is truthy) in conditions. For example, checking if a user object is loaded:
const user = fetchUser(); // Could return `null` or a user object
const isUserLoaded = !!user; // `true` if user exists, `false` if `null`3. Enforcing Boolean Return Types#
Functions that should always return a boolean (not a truthy/falsy value) can use !! to guarantee the type:
// Without `!!`, returns the array (truthy) or undefined (falsy)
function hasItems(arr) {
return arr?.length; // Returns number (truthy) or undefined (falsy)
}
// With `!!`, returns a boolean
function hasItems(arr) {
return !!arr?.length; // true/false (boolean)
}4. Simplifying Conditional Checks#
In cases where implicit coercion might be ambiguous, !! makes the intent clear:
// Implicit coercion (works but less clear)
if (user) { /* ... */ }
// Explicit boolean check (clearer intent)
if (!!user) { /* ... */ }Common Examples with Code#
Let’s test !! with different data types to see how it behaves.
Falsy Values (All Return false)#
// Falsy values → !! returns false
console.log(!!false); // false (boolean false)
console.log(!!0); // false (number zero)
console.log(!!-0); // false (negative zero)
console.log(!!0n); // false (BigInt zero)
console.log(!!""); // false (empty string)
console.log(!!null); // false (null)
console.log(!!undefined); // false (undefined)
console.log(!!NaN); // false (NaN)Truthy Values (All Return true)#
// Truthy values → !! returns true
console.log(!!true); // true (boolean true)
console.log(!!1); // true (positive number)
console.log(!!-1); // true (negative number)
console.log(!!42n); // true (non-zero BigInt)
console.log(!!"hello"); // true (non-empty string)
console.log(!!" "); // true (string with space)
console.log(!!{}); // true (empty object)
console.log(!![]); // true (empty array)
console.log(!!function(){}); // true (function)
console.log(!!Symbol()); // true (Symbol)Real-World Scenario: Form Validation#
Check if required form fields are filled (non-empty strings):
const formData = {
username: "alice",
email: "", // Empty string (falsy)
age: 25
};
// Check if all required fields are truthy
const isFormValid = !!formData.username && !!formData.email && !!formData.age;
console.log(isFormValid); // false (email is empty)Edge Cases and Considerations#
!![] and !!{} Are true#
Arrays and objects are always truthy, even if empty. This is because objects (including arrays) are considered "present" in JavaScript:
console.log(!![]); // true (empty array is truthy)
console.log(!!{}); // true (empty object is truthy)!!" " vs. !!""#
A string with whitespace (" ") is truthy (non-empty), while an empty string ("") is falsy:
console.log(!!" "); // true (space is a non-empty string)
console.log(!!""); // false (empty string)Equivalence to Boolean()#
!!value and Boolean(value) are identical in behavior. Use whichever is more readable for your team:
console.log(!!"test" === Boolean("test")); // true
console.log(!!0 === Boolean(0)); // trueWhen to Use (and When Not to Use) !!#
When to Use:#
- Clarity: Explicitly showing intent to convert to a boolean (avoids ambiguity in code reviews).
- Type Safety: Ensuring a value is strictly a boolean (e.g., for state variables or API responses).
- Conciseness: Shorter than
Boolean()for simple cases.
When Not to Use:#
- Implicit Coercion is Sufficient: In
ifconditions,if (value)works fine (no need forif (!!value)unless clarity demands it). - Readability Concerns: If your team finds
!!cryptic, useBoolean(value)instead (it’s more explicit for beginners).
Conclusion#
The !! operator is a simple yet powerful tool in JavaScript for converting values to their boolean equivalents. By applying the logical NOT operator twice, it explicitly coerces any value to true (if truthy) or false (if falsy).
While it’s equivalent to Boolean(), !! is favored for its conciseness in scenarios like checking value presence, enforcing boolean types, or simplifying conditions. As with any operator, use it judiciously—prioritize readability for your team.
To master !!, first understand JavaScript’s falsy/truthy values, then practice with different data types. You’ll soon find it indispensable in your code!