What is hidden behind two exclamation marks in JavaScript?
\n\nHave you ever encountered a strange construct like !!value in someone else's code and wondered: "Why are there two exclamation marks here?" If so — you are not alone. This question on Stack Overflow has gathered tens of thousands of views, and today we will break it down from start to finish.
Imagine: you are writing a function that should return true or false, but you pass a string, a number, or even an object. How will JavaScript understand what you meant? That's where our hero appears — the !! (double negation) operator.
Let's figure out how it works, why it is needed, and whether it should be used in real projects. Spoiler: it's not just "magic", but a powerful tool for performance optimization and code cleanliness.
\n\nHow does !! (double negation) work in JavaScript?
\n\nThe !! operator is based on a simple principle: converting any value to a boolean type. Let's break it down step by step:
- \n
- First ! — the logical NOT operator. It converts the value to boolean and inverts it. For example:
!"hello"→false(because "hello" is a truthy value). \n - Second ! — inverts the result again.
!!"hello"→true. \n
Simply put: !!value always returns true if the value is truthy, and false if it is falsy.
What are truthy and falsy?
\n\nIn JavaScript, all values are divided into two categories:
\n\n- \n
- Falsy:
false,0,""(empty string),null,undefined,NaN. \n - Truthy: everything else — strings, numbers (except 0), objects, arrays, functions,
true. \n
The !! operator is exactly what you need to quickly check whether your value is truthy or falsy.
Practical examples of using !!
\n\nLet's see how this works in real code. Here are a few typical scenarios:
\n\n1. Checking for the existence of an object property
\n\nconst user = {\n name: "Anna",\n email: "anna@example.com"\n};\n\n// Old way\nif (user.email !== undefined && user.email !== null && user.email !== "") {\n console.log("Email exists");\n}\n\n// Using !!\nif (!!user.email) {\n console.log("Email exists");\n}\n\nNotice the difference? The second option is much more readable and shorter.
\n\n2. Filtering arrays
\n\nconst values = [0, "hello", "", null, 42, undefined, "world"];\n\n// Get only truthy values\nconst truthyValues = values.filter(value => !!value);\nconsole.log(truthyValues); // ["hello", 42, "world"]\n\nNote: 0 and the empty string "" were filtered out because they are falsy.
3. Returning a boolean value from a function
\n\nfunction isUserActive(user) {\n // Let's say activity is stored as the string "active" or null\n return !!user.status;\n}\n\nconsole.log(isUserActive({ status: "active" })); // true\nconsole.log(isUserActive({ status: null })); // false\n\n!! and performance: myths and reality
\n\nMany developers argue: does !! affect performance? Let's find out.
In reality, the performance difference between !! and an explicit call to Boolean() is minimal. Modern JavaScript engines (V8, SpiderMonkey) optimize both approaches. But there are nuances:
\n\n- \n
!!value— these are just two operators that execute at the syntax level. No function calls. \n Boolean(value)— this is a function call