I saw some code that seems to use an operator I don't recognize, in the form of two exclamation points, like so: !!. Can someone please tell me what this operator does?
The context in which I saw this was,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
It converts Object to boolean. If it was falsey (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.
!object // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation
So !! is not an operator; it's just the ! operator twice.
It may be simpler to do:
Boolean(object) // Boolean
Real World Example "Test IE version":
const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false
If you ⇒
console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null
But if you ⇒
console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false
It's a horribly obscure way to do a type conversion.
! means NOT. So !true is false, and !false is true. !0 is true, and !1 is false.
So you're converting a value to a Boolean, inverting it, and then inverting it again.
// Maximum Obscurity:
val.enabled = !!userId;
// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;
// And finally, much easier to understand:
val.enabled = (userId != 0);
// Or just
val.enabled = Boolean(userId);
Note: the latter two expressions aren't exactly equivalent to the first expression when it comes to some edge case (when userId is [], for example), due to the way the != operator works and what values are considered truthy.
!!expr (two ! operators followed by an expression) returns a Boolean value (true or false) depending on the truthiness of the expression. It makes more sense when used on non-boolean types. Consider these examples, especially the 3rd example and onward:
!!false === false
!!true === true
!!0 === false
!!parseInt("foo") === false // NaN is falsy
!!1 === true
!!-1 === true // -1 is truthy
!!(1/0) === true // Infinity is truthy
!!"" === false // empty string is falsy
!!"foo" === true // non-empty string is truthy
!!"false" === true // ...even if it contains a falsy value
!!window.foo === false // undefined value is falsy
!!undefined === false // undefined primitive is falsy
!!null === false // null is falsy
!!{} === true // an (empty) object is truthy
!![] === true // an (empty) array is truthy; PHP programmers beware!
Brew some tea:
!! is not an operator. It is the double-use of ! -- which is the logical "not" operator.
In theory:
! determines the "truth" of what a value is not:
The truth is that false is not true (that's why !false results
in true)
The truth is that true is not false (that's why !true results
in false)
!! determines the "truth" of what a value is not not:
The truth is that true is not not true (that's why !!true results in true)
The truth is that false is not not false (that's why !!false results in false)
What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be false (or falsey), or if we expect the value not to be typeof boolean.
In practice:
Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns true if a user's browser supports the HTML5 <audio> element, but we don't want the function to throw an error if <audio> is undefined; and we don't want to use try ... catch to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example, document.createElement('audio') will still create an element called <audio> even if HTML5 <audio> is not supported).
Here are the three approaches:
// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }
// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }
// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }
foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true
Each function accepts an argument for a <tag> and an attribute to look for, but they each return different values based on what the comparisons determine.
But wait, there's more!
Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:
// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }
// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }
qux('audio', 'preload'); // returns true
quux('audio', 'preload'); // returns true
We digress...
However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting true from a non-boolean, possibly undefined value is indeed by using !!. Hopefully this ridiculously clears it up.
!! converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.
!!foo applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus +foo to cast to a number and concatenating an empty string ''+foo to cast to a string.
Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using new) to explicitly cast values, i.e.,
Boolean(foo) === !!foo
Number(foo) === +foo
String(foo) === ''+foo
So many answers doing half the work. Yes, !!X could be read as "the truthiness of X [represented as a Boolean]". But !! isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy. !!myVar === true is the same as just myVar. Comparing !!X to a "real" Boolean isn't really useful.
The only thing you gain with !! is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.
Simply casting :(
That is...
0 === false is false.
!!0 === false is true.
The above's not so useful. if (!0) gives you the same results as if (!!0 === false). I can't think of a good case for casting a variable to Boolean and then comparing to a "true" Boolean.
See "== and !=" from JSLint's directions (note: Crockford is moving his site around a bit; that link is liable to die at some point) for a little on why:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use == and != at all and to always use the more reliable === and !== operators instead.
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
Note that there are some unintuitive cases where a Boolean will be cast to a number (true is cast to 1 and false to 0) when comparing a Boolean to a number. In this case, !! might be mentally useful. Though, again, these are cases where you're comparing a non-Boolean to a hard-typed Boolean, which is, in my opinion, a serious mistake. if (-1) is still the way to go here.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
And things get even crazier depending on your engine. WScript, for instance, wins the prize.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But WScript.echo(-1 == test()) still gives you 0, or WScript's false. Look away. It's hideous.
Comparing truthiness :)
But what if I have two values I need to check for equal truthiness/falsiness?
Pretend we have myVar1 = 0; and myVar2 = undefined;.
myVar1 === myVar2 is 0 === undefined and is obviously false.
!!myVar1 === !!myVar2 is !!0 === !!undefined and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)
So the only place you'd really need to use "Boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use !! if you need to see if two variables are both truthy or both falsy (or not), that is, of equal (or not) truthiness.
I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your errorObjects collection.
Though even in this case, the !! really is superfluous. One ! was enough to cast to a Boolean, and you're just checking equality.
EDIT 24 Oct 2017, 6 Feb 19:
Third-party libraries that expect explicit Boolean values
Here's an interesting case... !! might be useful when third-party libraries expect explicit Boolean values.
React
For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in messageCount...
{messageCount && <div>You have messages!</div>}
... you might be surprised to see React render a 0 when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns 0, which JSX happily renders, as it should. It can't tell you didn't have Count: {messageCount}.
One fix involves the bangbang, which coerces 0 into !!0, which is false:
{!!messageCount && <div>You have messages!</div>}
JSX' documentation suggests you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
{messageCount > 0 && <div>You have messages!</div>}
I'm more comfortable handling falsiness myself with a ternary --
{messageCount ? <div>You have messages!</div> : false}
TypeScript
The same deal in TypeScript: If you have a function that returns a Boolean (or you're assigning a value to a Boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff myObject is strongly typed, return !myObject; works for a function returning a Boolean, but return myObject; doesn't. You have to return !!myObject (or cast to the proper Boolean another way) to match TypeScript's expectations.
The exception for TypeScript? If myObject was an any, you're back in JavaScript's Wild West and can return it without !!, even if your return type is a Boolean.
Keep in mind that these are JSX and TypeScript conventions, not ones inherent to JavaScript.
But if you see strange 0s in your rendered JSX, think loose falsy management.
It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:
true === !!10
false === !!0
It converts the suffix to a Boolean value.
It's a double not operation. The first ! converts the value to Boolean and inverts its logical value. The second ! inverts the logical value back.
It seems that the !! operator results in a double negation.
var foo = "Hello, World!";
!foo // Result: false
!!foo // Result: true
!! is using the NOT operation twice together. ! converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. Here is a simple example to see how !! works:
At first, the place you have:
var zero = 0;
Then you do !0. It will be converted to Boolean and be evaluated to true, because 0 is falsy, so you get the reversed value and converted to Boolean, so it gets evaluated to true.
!zero; //true
But we don't want the reversed Boolean version of the value, so we can reverse it again to get our result! That's why we use another !.
Basically, !! makes us sure the value we get is Boolean, not falsy, truthy, string, etc...
So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:
var zero = 0;
!!zero; //false
It simulates the behavior of the Boolean() casting function.
The first NOT returns a Boolean value no matter what operand it is given. The second NOT negates that Boolean value and so gives the true Boolean value of a variable. The end result is the same as using the Boolean() function on a value.
! is "Boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So, !!enable means "not not enable," giving you the value of enable as a Boolean.
I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of && and the first success or last fail in case of || of the condition chain.
res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'
In order to cast the condition to a true Boolean literal we can use the double negation:
res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
The !! construct is a simple way of turning any JavaScript expression into
its Boolean equivalent.
For example: !!"he shot me down" === true and !!0 === false.
It's not a single operator; it's two. It's equivalent to the following and is a quick way to cast a value to Boolean.
val.enabled = !(!enable);
It forces all things to Boolean.
For example:
console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false
console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true
console.log(0 === false); // -> false
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.
Because JavaScript has what are called "truthy" and "falsy" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually true or false.
For instance:
if (document.getElementById('myElement')) {
// Code block
}
If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.
However:
if (document.getElementById('myElement') == true) {
// Code block
}
...will not result in a true condition, and the code block will not be executed, even if the element does exist.
Why? Because document.getElementById() is a "truthy" expression that will evaluate as true in this if() statement, but it is not an actual Boolean value of true.
The double "not" in this case is quite simple. It is simply two nots back to back.
The first one simply "inverts" the truthy or falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its original state, but now in an actual Boolean value. That way you have consistency:
if (!!document.getElementById('myElement')) {}
and
if (!!document.getElementById('myElement') == true) {}
will both return true, as expected.
I suspect this is a leftover from C++ where people override the ! operator, but not the bool operator.
So to get a negative (or positive) answer in that case, you would first need to use the ! operator to get a Boolean, but if you wanted to check the positive case you would use !!.
The if and while statements and the ? operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value and null are both false.
The double negation operator !! calculates the truth value of a value. It's actually two operators, where !!x means !(!x), and behaves as follows:
If x is a false value, !x is true, and !!x is false.
If x is a true value, !x is false, and !!x is true.
When used at the top level of a Boolean context (if, while, or ?), the !! operator is behaviorally a no-op. For example, if (x) and if (!!x) mean the same thing.
Practical uses
However it has several practical uses.
One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning !!some_big_object to a variable instead of some_big_object lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such as null or the undefined value, such as browser feature detection.
Another use, which I mentioned in an answer about C's corresponding !! operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:
if (a = b) is assignment followed by use of the truth value of b; if (a == b) is an equality comparison.
if (a & b) is a bitwise AND; if (a && b) is a logical AND. 2 & 5 is 0 (a false value); 2 && 5 is true.
The !! operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.
A third use is to produce logical XOR and logical XNOR. In both C and JavaScript, a && b performs a logical AND (true if both sides are true), and a & b performs a bitwise AND. a || b performs a logical OR (true if at least one are true), and a | b performs a bitwise OR. There's a bitwise XOR (exclusive OR) as a ^ b, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them: !!x !== !!y.
I just wanted to add that
if(variableThing){
// do something
}
is the same as
if(!!variableThing){
// do something
}
But this can be an issue when something is undefined.
// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};
// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar
a.foo
b.foo.bar
// This works -- these return undefined
a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar
The trick here is the chain of &&s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip the b.foo.bar statement, and we get no error.
The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain -- [] and {} are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.
P.S. Another way of doing the above (b && b.foo) is (b || {}).foo. Those are equivalent, because if b is undefined then b || {} will be {}, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error).
So, (b || {}).foo is the same as b && b.foo and ((b || {}).foo || {}).bar is the same as b && b.foo && b.foo.bar.
It is double Boolean negation. It is often used to check if a value is not undefined.
!!x is shorthand for Boolean(x).
The first bang forces the JavaScript engine to run Boolean(x), but it also has the side effect of inverting the value. So the second bang undoes the side effect.
There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in Chrome (etc.), and start typing:
!(!(1))
!(!(0))
!(!('truthy'))
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc., etc., until the light goes on ;)
Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.
After seeing all these great answers, I would like to add another reason for using !!. Currently I'm working in Angular 2-4 (TypeScript) and I want to return a Boolean as false when my user is not authenticated. If he isn't authenticated, the token-string would be null or "". I can do this by using the next block of code:
public isAuthenticated(): boolean {
return !!this.getToken();
}
It returns the Boolean value of a variable.
Instead, the Boolean class can be used.
(Please read the code descriptions.)
var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because non-empty strings evaluates as `true` in Boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // Writes `true`
Namely, Boolean(X) = !!X in use.
Please check code snippet out below ↓
let a = 0
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a) // Writes '0 is NOT true in Boolean' value as Boolean - so that's true. In Boolean, 0 means false and 1 means true.
console.log("!!a: ", !!a) // Writes 0 value in Boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // Equals `!!a`
console.log("\n") // Newline
a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes 1 value in Boolean
console.log("\n") // Newline
a = ""
console.log("a: ", a)
console.log("!a: ", !a) // Writes '"" is NOT true in Boolean' value as Boolean - so that's true. In Boolean, empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // Writes "" value in Boolean
console.log("\n") // Newline
a = "test"
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes "test" value in Boolean
console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
It is important to remember the evaluations to true and false in JavaScript:
Everything with a "Value" is true (namely truthy), for example:
101,
3.1415,
-11,
"Lucky Brain",
new Object()
and, of course, true
Everything without a "Value" is false (namely falsy), for example:
0,
-0,
"" (empty string),
undefined,
null,
NaN (not a number)
and, of course, false
Applying the "logical not" operator (!) evaluates the operand, converting it to boolean and then negating it. Applying it twice will negate the negation, effectively converting the value to boolean. Not applying the operator will just be a regular assignment of the exact value. Examples:
var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23
var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
value2 = value; assigns the exact object value even if it is not boolean hence value2 won't necessarily end up being boolean.
value2 = !!value; assigns a guaranteed boolean as the result of the double negation of the operand value and it is equivalent to the following but much shorter and readable:
if (value) {
value2 = true;
} else {
value2 = false;
}
Here is a piece of code from AngularJS:
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame ||
$window.mozRequestAnimationFrame;
var rafSupported = !!requestAnimationFrame;
Their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame.
It can be achieved by checking in the following way in general:
if(typeof requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;
The short way could be using !!
rafSupported = !!requestAnimationFrame;
So if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more ! of it would be true.
If requestAnimationFrame was assigned undefined then !requestAnimationFrame would be true and one more ! of it would be false.
Use the logical not operator two times.
It means !true = false and !!true = true.
Related
I saw some code that seems to use an operator I don't recognize, in the form of two exclamation points, like so: !!. Can someone please tell me what this operator does?
The context in which I saw this was,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
It converts Object to boolean. If it was falsey (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.
!object // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation
So !! is not an operator; it's just the ! operator twice.
It may be simpler to do:
Boolean(object) // Boolean
Real World Example "Test IE version":
const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false
If you ⇒
console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null
But if you ⇒
console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false
It's a horribly obscure way to do a type conversion.
! means NOT. So !true is false, and !false is true. !0 is true, and !1 is false.
So you're converting a value to a Boolean, inverting it, and then inverting it again.
// Maximum Obscurity:
val.enabled = !!userId;
// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;
// And finally, much easier to understand:
val.enabled = (userId != 0);
// Or just
val.enabled = Boolean(userId);
Note: the latter two expressions aren't exactly equivalent to the first expression when it comes to some edge case (when userId is [], for example), due to the way the != operator works and what values are considered truthy.
!!expr (two ! operators followed by an expression) returns a Boolean value (true or false) depending on the truthiness of the expression. It makes more sense when used on non-boolean types. Consider these examples, especially the 3rd example and onward:
!!false === false
!!true === true
!!0 === false
!!parseInt("foo") === false // NaN is falsy
!!1 === true
!!-1 === true // -1 is truthy
!!(1/0) === true // Infinity is truthy
!!"" === false // empty string is falsy
!!"foo" === true // non-empty string is truthy
!!"false" === true // ...even if it contains a falsy value
!!window.foo === false // undefined value is falsy
!!undefined === false // undefined primitive is falsy
!!null === false // null is falsy
!!{} === true // an (empty) object is truthy
!![] === true // an (empty) array is truthy; PHP programmers beware!
Brew some tea:
!! is not an operator. It is the double-use of ! -- which is the logical "not" operator.
In theory:
! determines the "truth" of what a value is not:
The truth is that false is not true (that's why !false results
in true)
The truth is that true is not false (that's why !true results
in false)
!! determines the "truth" of what a value is not not:
The truth is that true is not not true (that's why !!true results in true)
The truth is that false is not not false (that's why !!false results in false)
What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be false (or falsey), or if we expect the value not to be typeof boolean.
In practice:
Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns true if a user's browser supports the HTML5 <audio> element, but we don't want the function to throw an error if <audio> is undefined; and we don't want to use try ... catch to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example, document.createElement('audio') will still create an element called <audio> even if HTML5 <audio> is not supported).
Here are the three approaches:
// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }
// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }
// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }
foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true
Each function accepts an argument for a <tag> and an attribute to look for, but they each return different values based on what the comparisons determine.
But wait, there's more!
Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:
// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }
// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }
qux('audio', 'preload'); // returns true
quux('audio', 'preload'); // returns true
We digress...
However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting true from a non-boolean, possibly undefined value is indeed by using !!. Hopefully this ridiculously clears it up.
!! converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.
!!foo applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus +foo to cast to a number and concatenating an empty string ''+foo to cast to a string.
Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using new) to explicitly cast values, i.e.,
Boolean(foo) === !!foo
Number(foo) === +foo
String(foo) === ''+foo
So many answers doing half the work. Yes, !!X could be read as "the truthiness of X [represented as a Boolean]". But !! isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy. !!myVar === true is the same as just myVar. Comparing !!X to a "real" Boolean isn't really useful.
The only thing you gain with !! is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.
Simply casting :(
That is...
0 === false is false.
!!0 === false is true.
The above's not so useful. if (!0) gives you the same results as if (!!0 === false). I can't think of a good case for casting a variable to Boolean and then comparing to a "true" Boolean.
See "== and !=" from JSLint's directions (note: Crockford is moving his site around a bit; that link is liable to die at some point) for a little on why:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use == and != at all and to always use the more reliable === and !== operators instead.
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
Note that there are some unintuitive cases where a Boolean will be cast to a number (true is cast to 1 and false to 0) when comparing a Boolean to a number. In this case, !! might be mentally useful. Though, again, these are cases where you're comparing a non-Boolean to a hard-typed Boolean, which is, in my opinion, a serious mistake. if (-1) is still the way to go here.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
And things get even crazier depending on your engine. WScript, for instance, wins the prize.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But WScript.echo(-1 == test()) still gives you 0, or WScript's false. Look away. It's hideous.
Comparing truthiness :)
But what if I have two values I need to check for equal truthiness/falsiness?
Pretend we have myVar1 = 0; and myVar2 = undefined;.
myVar1 === myVar2 is 0 === undefined and is obviously false.
!!myVar1 === !!myVar2 is !!0 === !!undefined and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)
So the only place you'd really need to use "Boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use !! if you need to see if two variables are both truthy or both falsy (or not), that is, of equal (or not) truthiness.
I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your errorObjects collection.
Though even in this case, the !! really is superfluous. One ! was enough to cast to a Boolean, and you're just checking equality.
EDIT 24 Oct 2017, 6 Feb 19:
Third-party libraries that expect explicit Boolean values
Here's an interesting case... !! might be useful when third-party libraries expect explicit Boolean values.
React
For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in messageCount...
{messageCount && <div>You have messages!</div>}
... you might be surprised to see React render a 0 when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns 0, which JSX happily renders, as it should. It can't tell you didn't have Count: {messageCount}.
One fix involves the bangbang, which coerces 0 into !!0, which is false:
{!!messageCount && <div>You have messages!</div>}
JSX' documentation suggests you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
{messageCount > 0 && <div>You have messages!</div>}
I'm more comfortable handling falsiness myself with a ternary --
{messageCount ? <div>You have messages!</div> : false}
TypeScript
The same deal in TypeScript: If you have a function that returns a Boolean (or you're assigning a value to a Boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff myObject is strongly typed, return !myObject; works for a function returning a Boolean, but return myObject; doesn't. You have to return !!myObject (or cast to the proper Boolean another way) to match TypeScript's expectations.
The exception for TypeScript? If myObject was an any, you're back in JavaScript's Wild West and can return it without !!, even if your return type is a Boolean.
Keep in mind that these are JSX and TypeScript conventions, not ones inherent to JavaScript.
But if you see strange 0s in your rendered JSX, think loose falsy management.
It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:
true === !!10
false === !!0
It converts the suffix to a Boolean value.
It's a double not operation. The first ! converts the value to Boolean and inverts its logical value. The second ! inverts the logical value back.
It seems that the !! operator results in a double negation.
var foo = "Hello, World!";
!foo // Result: false
!!foo // Result: true
!! is using the NOT operation twice together. ! converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. Here is a simple example to see how !! works:
At first, the place you have:
var zero = 0;
Then you do !0. It will be converted to Boolean and be evaluated to true, because 0 is falsy, so you get the reversed value and converted to Boolean, so it gets evaluated to true.
!zero; //true
But we don't want the reversed Boolean version of the value, so we can reverse it again to get our result! That's why we use another !.
Basically, !! makes us sure the value we get is Boolean, not falsy, truthy, string, etc...
So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:
var zero = 0;
!!zero; //false
It simulates the behavior of the Boolean() casting function.
The first NOT returns a Boolean value no matter what operand it is given. The second NOT negates that Boolean value and so gives the true Boolean value of a variable. The end result is the same as using the Boolean() function on a value.
! is "Boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So, !!enable means "not not enable," giving you the value of enable as a Boolean.
I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of && and the first success or last fail in case of || of the condition chain.
res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'
In order to cast the condition to a true Boolean literal we can use the double negation:
res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
The !! construct is a simple way of turning any JavaScript expression into
its Boolean equivalent.
For example: !!"he shot me down" === true and !!0 === false.
It's not a single operator; it's two. It's equivalent to the following and is a quick way to cast a value to Boolean.
val.enabled = !(!enable);
It forces all things to Boolean.
For example:
console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false
console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true
console.log(0 === false); // -> false
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.
Because JavaScript has what are called "truthy" and "falsy" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually true or false.
For instance:
if (document.getElementById('myElement')) {
// Code block
}
If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.
However:
if (document.getElementById('myElement') == true) {
// Code block
}
...will not result in a true condition, and the code block will not be executed, even if the element does exist.
Why? Because document.getElementById() is a "truthy" expression that will evaluate as true in this if() statement, but it is not an actual Boolean value of true.
The double "not" in this case is quite simple. It is simply two nots back to back.
The first one simply "inverts" the truthy or falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its original state, but now in an actual Boolean value. That way you have consistency:
if (!!document.getElementById('myElement')) {}
and
if (!!document.getElementById('myElement') == true) {}
will both return true, as expected.
I suspect this is a leftover from C++ where people override the ! operator, but not the bool operator.
So to get a negative (or positive) answer in that case, you would first need to use the ! operator to get a Boolean, but if you wanted to check the positive case you would use !!.
The if and while statements and the ? operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value and null are both false.
The double negation operator !! calculates the truth value of a value. It's actually two operators, where !!x means !(!x), and behaves as follows:
If x is a false value, !x is true, and !!x is false.
If x is a true value, !x is false, and !!x is true.
When used at the top level of a Boolean context (if, while, or ?), the !! operator is behaviorally a no-op. For example, if (x) and if (!!x) mean the same thing.
Practical uses
However it has several practical uses.
One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning !!some_big_object to a variable instead of some_big_object lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such as null or the undefined value, such as browser feature detection.
Another use, which I mentioned in an answer about C's corresponding !! operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:
if (a = b) is assignment followed by use of the truth value of b; if (a == b) is an equality comparison.
if (a & b) is a bitwise AND; if (a && b) is a logical AND. 2 & 5 is 0 (a false value); 2 && 5 is true.
The !! operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.
A third use is to produce logical XOR and logical XNOR. In both C and JavaScript, a && b performs a logical AND (true if both sides are true), and a & b performs a bitwise AND. a || b performs a logical OR (true if at least one are true), and a | b performs a bitwise OR. There's a bitwise XOR (exclusive OR) as a ^ b, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them: !!x !== !!y.
I just wanted to add that
if(variableThing){
// do something
}
is the same as
if(!!variableThing){
// do something
}
But this can be an issue when something is undefined.
// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};
// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar
a.foo
b.foo.bar
// This works -- these return undefined
a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar
The trick here is the chain of &&s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip the b.foo.bar statement, and we get no error.
The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain -- [] and {} are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.
P.S. Another way of doing the above (b && b.foo) is (b || {}).foo. Those are equivalent, because if b is undefined then b || {} will be {}, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error).
So, (b || {}).foo is the same as b && b.foo and ((b || {}).foo || {}).bar is the same as b && b.foo && b.foo.bar.
It is double Boolean negation. It is often used to check if a value is not undefined.
!!x is shorthand for Boolean(x).
The first bang forces the JavaScript engine to run Boolean(x), but it also has the side effect of inverting the value. So the second bang undoes the side effect.
There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in Chrome (etc.), and start typing:
!(!(1))
!(!(0))
!(!('truthy'))
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc., etc., until the light goes on ;)
Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.
After seeing all these great answers, I would like to add another reason for using !!. Currently I'm working in Angular 2-4 (TypeScript) and I want to return a Boolean as false when my user is not authenticated. If he isn't authenticated, the token-string would be null or "". I can do this by using the next block of code:
public isAuthenticated(): boolean {
return !!this.getToken();
}
It returns the Boolean value of a variable.
Instead, the Boolean class can be used.
(Please read the code descriptions.)
var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because non-empty strings evaluates as `true` in Boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // Writes `true`
Namely, Boolean(X) = !!X in use.
Please check code snippet out below ↓
let a = 0
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a) // Writes '0 is NOT true in Boolean' value as Boolean - so that's true. In Boolean, 0 means false and 1 means true.
console.log("!!a: ", !!a) // Writes 0 value in Boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // Equals `!!a`
console.log("\n") // Newline
a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes 1 value in Boolean
console.log("\n") // Newline
a = ""
console.log("a: ", a)
console.log("!a: ", !a) // Writes '"" is NOT true in Boolean' value as Boolean - so that's true. In Boolean, empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // Writes "" value in Boolean
console.log("\n") // Newline
a = "test"
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes "test" value in Boolean
console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
It is important to remember the evaluations to true and false in JavaScript:
Everything with a "Value" is true (namely truthy), for example:
101,
3.1415,
-11,
"Lucky Brain",
new Object()
and, of course, true
Everything without a "Value" is false (namely falsy), for example:
0,
-0,
"" (empty string),
undefined,
null,
NaN (not a number)
and, of course, false
Applying the "logical not" operator (!) evaluates the operand, converting it to boolean and then negating it. Applying it twice will negate the negation, effectively converting the value to boolean. Not applying the operator will just be a regular assignment of the exact value. Examples:
var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23
var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
value2 = value; assigns the exact object value even if it is not boolean hence value2 won't necessarily end up being boolean.
value2 = !!value; assigns a guaranteed boolean as the result of the double negation of the operand value and it is equivalent to the following but much shorter and readable:
if (value) {
value2 = true;
} else {
value2 = false;
}
Here is a piece of code from AngularJS:
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame ||
$window.mozRequestAnimationFrame;
var rafSupported = !!requestAnimationFrame;
Their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame.
It can be achieved by checking in the following way in general:
if(typeof requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;
The short way could be using !!
rafSupported = !!requestAnimationFrame;
So if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more ! of it would be true.
If requestAnimationFrame was assigned undefined then !requestAnimationFrame would be true and one more ! of it would be false.
Use the logical not operator two times.
It means !true = false and !!true = true.
I'm trying to learn JavaScript by going through some code in an application and I keep seeing !variable in if conditions. For example:
if (!variable.onsubmit || (variable.onsubmit() != false)) {
What is it? Some kind of test if the variable is empty?
! is the logical not operator in JavaScript.
Formally
!expression is read as:
Take expression and evaluate it. In your case that's variable.onsubmit
Case the result of that evaluation and convert it to a boolean. In your case since onsubmit is likely a function, it means - if the function is null or undefined - return false, otherwise return true.
If that evaluation is true, return false. Otherwise return true.
In your case
In your case !variable.onsubmit means return true if there isn't a function defined (and thus is falsy), otherwise return false (since there is a function defined).
Simply put - !variable means take the truth value of variable and negate it.
Thus, if (!variable) { will enter the if clause if variable is false (or coerces to false)
In total
if (!variable.onsubmit || (variable.onsubmit() != false)) {
Means - check if variable.onsubmit is defined and truthy (thus true), then it checks if calling onsubmit returns a result that coerces to true. In a short line it checks if there is no onsubmit or it returns true.
Next time, how do I find this myself?
MDN has a list of operators here.
The language specification specifies such operators, though being the official specification it does contain some jargon which might be hard to understand.
It is a negation operator used for truth tests on a variable.
var myVariable = 1;
if ( ! myVariable )
{
// myVariable evaluates as false
}
if ( myVariable )
{
// myVariable evaluates as true
}
The selected answer already answers the question. One thing to add in this is that ! operator can be used in a rather interesting fashion.
obj = {}
if (!!obj) {console.log('works')} // !!obj = true
obj = undefined
if (!!obj) {console.log('does not work')} // !!obj = false
So double !! will change any expression to a boolean value with no exceptions.
This has a very peculiar use case in some cases.
Lets say there is a function that returns either true or false and nothing else. In that case one could just change return returnValue to return !!returnValue for extra caution (although not need in most of the cases)
Conversely, if a function only accepts true or false and nothing else, one could just call the function as functionA(!!parameter) instead of functionA(parameter), which again is not needed in most of the cases, but could ensure extra security
! is a logic reversal operator, if something was true it will change it to false, if something is false, it will change to true.
example, we know that empty string or 0 in boolean is false.
let a = Boolean("")
console.log(a) // shows false, because empty string in boolean is false
console.log(!a) // shows true, because logic is reversed
easier example:
let a = 5
let b = 1
let c = a > b
console.log(c) // shows true, since a,5 is bigger than b,1
console.log(!c) // shows false, since logic is now reversed
If we alert(null==undefined) it outputs to true.
What is the logical reason for this.
Is this something that is hard coded in javascript or is there an explanation for this.
The language specification explicitly says:
If x is null and y is undefined, return true
I'm not aware of any records of the language design process that explain the reasoning for that decision, but == has rules for handling different types, and "null" and "undefined" are both things that mean "nothing", so having them be equal makes intuitive sense.
(If you don't want type fiddling, use === instead).
Using the double-equal operator forces Javascript to do type coercion.
In other words, when you do x == y, if x and y are not of the same type, JavaScript will cast one value to another before comparing, like if string and number are compared, the string is always cast into a number and then compared
For this reason, many comparisons of mixed types in JavaScript can result in results that may be unexpected or counter-intuitive.
If you want to do comparisons in JavaScript, it is usually a better idea to use the triple-equal operator === rather than double-equal. This does not do a type coercion; instead if the types are different, it returns false. This is more usually what you need.
You should only use double-equal if you are absolutely certain that you need it.
For the same reason that 0 == "0" - javascript is loosely typed - if something can be converted to something else then it will be unless you use ===
alert(null===undefined);
Will give you false.
As for why these particular conversions happen - the answer is quite simply "the spec says that is what should happen". There doesn't need to be a reason other than "because it says so" for why programming language behave in certain ways.
Edit: Slightly better answer - in Javascript, certain objects/values are 'truthy' or 'falsey' when converted to a boolean. 0 (integer zero), "0" (character zero in a string), "" (empty string) are all false. If there isn't a better comparison to use then the boolean operation applies.
This is why "0" is not equal to an empty string, but both "0" and "" are both equal to false.
we know,
If x is null and y is undefined, return true
undefined == null => true, reason might be both are converted to boolean, as we know javascript performs the type conversion. so that will be resulting the null and undefined converted to false and false == false is true
A better explanation...
In the case of "==" or Loose Equality Operator, if one of the operands is null or undefined and the other is null or undefined, always return true. Otherwise return false. Unlike what other posters falsely state, these are not converted or coerced into new types when using equality operators, but simply follow the rule above.
// TRUE - loose equality operator says use the null vs. undefined rule above which equates them
console.log(null == undefined);
// FALSE - strict equality operator says these are not of the same type, so always return false
console.log(null === undefined);
The == comparison operator doesn't check the types. null and undefined both return false. That's why your code is actually checking if false is equal to false.
> null == undefined;
< true
> false == false
< true
However their types are not equal.
> typeof undefined;
< "undefined"
> typeof null;
< "object"
Because of that, the next statement will return false, as the === comparison operator checks both the types and their value.
> undefined === null;
< false
I was reading a good book on JavaScript.
It started with:
Boolean type take only two literal values: true and false. These are distinct from numeric values, so true is not equal to 1, and false is not equal to 0.
However, I observed following:
if(1==true)
document.write("oh!!! that's true"); //**this is displayed**
I know, that every type in JavaScript has a Boolean equivalent.
But then, what's the truth?
It's true that true and false don't represent any numerical values in Javascript.
In some languages (e.g. C, VB), the boolean values are defined as actual numerical values, so they are just different names for 1 and 0 (or -1 and 0).
In some other languages (e.g. Pascal, C#), there is a distinct boolean type that is not numerical. It's possible to convert between boolean values and numerical values, but it doesn't happen automatically.
Javascript falls in the category that has a distinct boolean type, but on the other hand Javascript is quite keen to convert values between different data types.
For example, eventhough a number is not a boolean, you can use a numeric value where a boolean value is expected. Using if (1) {...} works just as well as if (true) {...}.
When comparing values, like in your example, there is a difference between the == operator and the === operator. The == equality operator happily converts between types to find a match, so 1 == true evaluates to true because true is converted to 1. The === type equality operator doesn't do type conversions, so 1 === true evaluates to false because the values are of different types.
In JavaScript, == is pronounced "Probably Equals".
What I mean by that is that JavaScript will automatically convert the Boolean into an integer and then attempt to compare the two sides.
For real equality, use the === operator.
Try the strict equality comparison:
if(1 === true)
document.write("oh!!! that's true"); //**this is not displayed**
The == operator does conversion from one type to another, the === operator doesn't.
From the ECMAScript specification, Section 11.9.3 The Abstract Equality Comparison Algorithm:
The comparison x == y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
Thus, in, if (1 == true), true gets coerced to a Number, i.e. Number(true), which results in the value of 1, yielding the final if (1 == 1) which is true.
if (0 == false) is the exact same logic, since Number(false) == 0.
This doesn't happen when you use the strict equals operator === instead:
11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
If Type(x) is different from Type(y), return false.
Ah, the dreaded loose comparison operator strikes again. Never use it. Always use strict comparison, === or !== instead.
Bonus fact: 0 == ''
When compare something with Boolean it works like following
Step 1: Convert boolean to Number Number(true) // 1 and Number(false) // 0
Step 2: Compare both sides
boolean == someting
-> Number(boolean) === someting
If compare 1 and 2 with true you will get the following results
true == 1
-> Number(true) === 1
-> 1 === 1
-> true
And
true == 2
-> Number(true) === 1
-> 1 === 2
-> false
Actually every object in javascript resolves to true if it has "a real value" as W3Cschools puts it. That means everything except "", NaN, undefined, null or 0.
Testing a number against a boolean with the == operator indeed is a tad weird, since the boolean gets converted into numerical 1 before comparing, which defies a little bit the logic behind the definition.
This gets even more confusing when you do something like this:
var fred = !!3; // will set fred to true
var joe = !!0; // will set joe to false
alert("fred = "+ fred + ", joe = "+ joe);
not everything in javascript makes a lot of sense ;)
Use === to equate the variables instead of ==.
== checks if the value of the variables is similar
=== checks if the value of the variables and the type of the variables are similar
Notice how
if(0===false) {
document.write("oh!!! that's true");
}
and
if(0==false) {
document.write("oh!!! that's true");
}
give different results
In a way, yes it is 1.
Try these examples in Chrome console:
> 2==true
false
> 1==true
true
> true + 1
2
> true + 2
3
> true + true
2
So, the answer is:
yes, as soon as you use true in any arithmetical context, it's treated as numeric 1, or as Bruce Lee would say, it becomes one. The same way, false is practically zero. But also,
no, if you ask Javascript what it thinks of true, it will say it's a boolean:
> typeof true
'boolean'
It's no surprise in a loosely typed language that sometimes things are not what they are but how you look at them. And if you add true to a string, it will not add 1 but "true" as a string, so at the end of the day, it's by no means equivalent to one. Let me end this with a horrible pun:
true is not a number - but it looks like one
with == you are essentially comparing whether a variable is falsey when comparing to false or truthey when comparing to true. If you use ===, it will compare the exact value of the variables so true will not === 1
I saw some code that seems to use an operator I don't recognize, in the form of two exclamation points, like so: !!. Can someone please tell me what this operator does?
The context in which I saw this was,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
It converts Object to boolean. If it was falsey (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.
!object // Inverted Boolean
!!object // Noninverted Boolean, so true Boolean representation
So !! is not an operator; it's just the ! operator twice.
It may be simpler to do:
Boolean(object) // Boolean
Real World Example "Test IE version":
const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // Returns true or false
If you ⇒
console.log(navigator.userAgent.match(/MSIE 8.0/));
// Returns either an Array or null
But if you ⇒
console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// Returns either true or false
It's a horribly obscure way to do a type conversion.
! means NOT. So !true is false, and !false is true. !0 is true, and !1 is false.
So you're converting a value to a Boolean, inverting it, and then inverting it again.
// Maximum Obscurity:
val.enabled = !!userId;
// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;
// And finally, much easier to understand:
val.enabled = (userId != 0);
// Or just
val.enabled = Boolean(userId);
Note: the latter two expressions aren't exactly equivalent to the first expression when it comes to some edge case (when userId is [], for example), due to the way the != operator works and what values are considered truthy.
!!expr (two ! operators followed by an expression) returns a Boolean value (true or false) depending on the truthiness of the expression. It makes more sense when used on non-boolean types. Consider these examples, especially the 3rd example and onward:
!!false === false
!!true === true
!!0 === false
!!parseInt("foo") === false // NaN is falsy
!!1 === true
!!-1 === true // -1 is truthy
!!(1/0) === true // Infinity is truthy
!!"" === false // empty string is falsy
!!"foo" === true // non-empty string is truthy
!!"false" === true // ...even if it contains a falsy value
!!window.foo === false // undefined value is falsy
!!undefined === false // undefined primitive is falsy
!!null === false // null is falsy
!!{} === true // an (empty) object is truthy
!![] === true // an (empty) array is truthy; PHP programmers beware!
Brew some tea:
!! is not an operator. It is the double-use of ! -- which is the logical "not" operator.
In theory:
! determines the "truth" of what a value is not:
The truth is that false is not true (that's why !false results
in true)
The truth is that true is not false (that's why !true results
in false)
!! determines the "truth" of what a value is not not:
The truth is that true is not not true (that's why !!true results in true)
The truth is that false is not not false (that's why !!false results in false)
What we wish to determine in the comparison is the "truth" about the value of a reference, not the value of the reference itself. There is a use-case where we might want to know the truth about a value, even if we expect the value to be false (or falsey), or if we expect the value not to be typeof boolean.
In practice:
Consider a concise function which detects feature functionality (and in this case, platform compatibility) by way of dynamic typing (aka "duck typing"). We want to write a function that returns true if a user's browser supports the HTML5 <audio> element, but we don't want the function to throw an error if <audio> is undefined; and we don't want to use try ... catch to handle any possible errors (because they're gross); and also we don't want to use a check inside the function that won't consistently reveal the truth about the feature (for example, document.createElement('audio') will still create an element called <audio> even if HTML5 <audio> is not supported).
Here are the three approaches:
// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }
// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }
// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }
foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true
Each function accepts an argument for a <tag> and an attribute to look for, but they each return different values based on what the comparisons determine.
But wait, there's more!
Some of you probably noticed that in this specific example, one could simply check for a property using the slightly more performant means of checking if the object in question has a property. There are two ways to do this:
// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }
// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }
qux('audio', 'preload'); // returns true
quux('audio', 'preload'); // returns true
We digress...
However rare these situations may be, there may exist a few scenarios where the most concise, most performant, and thus most preferred means of getting true from a non-boolean, possibly undefined value is indeed by using !!. Hopefully this ridiculously clears it up.
!! converts the value to the right of it to its equivalent Boolean value. (Think poor man's way of "type-casting".) Its intent is usually to convey to the reader that the code does not care what value is in the variable, but what its "truth" value is.
!!foo applies the unary not operator twice and is used to cast to a Boolean type similar to the use of unary plus +foo to cast to a number and concatenating an empty string ''+foo to cast to a string.
Instead of these hacks, you can also use the constructor functions corresponding to the primitive types (without using new) to explicitly cast values, i.e.,
Boolean(foo) === !!foo
Number(foo) === +foo
String(foo) === ''+foo
So many answers doing half the work. Yes, !!X could be read as "the truthiness of X [represented as a Boolean]". But !! isn't, practically speaking, so important for figuring out whether a single variable is (or even if many variables are) truthy or falsy. !!myVar === true is the same as just myVar. Comparing !!X to a "real" Boolean isn't really useful.
The only thing you gain with !! is the ability to check the truthiness of multiple variables against each other in a repeatable, standardized (and JSLint friendly) fashion.
Simply casting :(
That is...
0 === false is false.
!!0 === false is true.
The above's not so useful. if (!0) gives you the same results as if (!!0 === false). I can't think of a good case for casting a variable to Boolean and then comparing to a "true" Boolean.
See "== and !=" from JSLint's directions (note: Crockford is moving his site around a bit; that link is liable to die at some point) for a little on why:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use == and != at all and to always use the more reliable === and !== operators instead.
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
Note that there are some unintuitive cases where a Boolean will be cast to a number (true is cast to 1 and false to 0) when comparing a Boolean to a number. In this case, !! might be mentally useful. Though, again, these are cases where you're comparing a non-Boolean to a hard-typed Boolean, which is, in my opinion, a serious mistake. if (-1) is still the way to go here.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
And things get even crazier depending on your engine. WScript, for instance, wins the prize.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Because of some historical Windows jive, that'll output -1 in a message box! Try it in a cmd.exe prompt and see! But WScript.echo(-1 == test()) still gives you 0, or WScript's false. Look away. It's hideous.
Comparing truthiness :)
But what if I have two values I need to check for equal truthiness/falsiness?
Pretend we have myVar1 = 0; and myVar2 = undefined;.
myVar1 === myVar2 is 0 === undefined and is obviously false.
!!myVar1 === !!myVar2 is !!0 === !!undefined and is true! Same truthiness! (In this case, both "have a truthiness of falsy".)
So the only place you'd really need to use "Boolean-cast variables" would be if you had a situation where you're checking if both variables have the same truthiness, right? That is, use !! if you need to see if two variables are both truthy or both falsy (or not), that is, of equal (or not) truthiness.
I can't think of a great, non-contrived use case for that offhand. Maybe you have "linked" fields in a form?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
So now if you have a truthy for both or a falsy for both spouse name and age, you can continue. Otherwise you've only got one field with a value (or a very early arranged marriage) and need to create an extra error on your errorObjects collection.
Though even in this case, the !! really is superfluous. One ! was enough to cast to a Boolean, and you're just checking equality.
EDIT 24 Oct 2017, 6 Feb 19:
Third-party libraries that expect explicit Boolean values
Here's an interesting case... !! might be useful when third-party libraries expect explicit Boolean values.
React
For instance, False in JSX (React) has a special meaning that's not triggered on simple falsiness. If you tried returning something like the following in your JSX, expecting an int in messageCount...
{messageCount && <div>You have messages!</div>}
... you might be surprised to see React render a 0 when you have zero messages. You have to explicitly return false for JSX not to render. The above statement returns 0, which JSX happily renders, as it should. It can't tell you didn't have Count: {messageCount}.
One fix involves the bangbang, which coerces 0 into !!0, which is false:
{!!messageCount && <div>You have messages!</div>}
JSX' documentation suggests you be more explicit, write self-commenting code, and use a comparison to force to a Boolean.
{messageCount > 0 && <div>You have messages!</div>}
I'm more comfortable handling falsiness myself with a ternary --
{messageCount ? <div>You have messages!</div> : false}
TypeScript
The same deal in TypeScript: If you have a function that returns a Boolean (or you're assigning a value to a Boolean variable), you [usually] can't return/assign a boolean-y value; it has to be a strongly typed boolean. This means, iff myObject is strongly typed, return !myObject; works for a function returning a Boolean, but return myObject; doesn't. You have to return !!myObject (or cast to the proper Boolean another way) to match TypeScript's expectations.
The exception for TypeScript? If myObject was an any, you're back in JavaScript's Wild West and can return it without !!, even if your return type is a Boolean.
Keep in mind that these are JSX and TypeScript conventions, not ones inherent to JavaScript.
But if you see strange 0s in your rendered JSX, think loose falsy management.
It's just the logical NOT operator, twice. It's used to convert something to Boolean, e.g.:
true === !!10
false === !!0
It converts the suffix to a Boolean value.
It's a double not operation. The first ! converts the value to Boolean and inverts its logical value. The second ! inverts the logical value back.
It seems that the !! operator results in a double negation.
var foo = "Hello, World!";
!foo // Result: false
!!foo // Result: true
!! is using the NOT operation twice together. ! converts the value to a Boolean and reverses it, so using it twice, showing the Boolean (false or true) of that value. Here is a simple example to see how !! works:
At first, the place you have:
var zero = 0;
Then you do !0. It will be converted to Boolean and be evaluated to true, because 0 is falsy, so you get the reversed value and converted to Boolean, so it gets evaluated to true.
!zero; //true
But we don't want the reversed Boolean version of the value, so we can reverse it again to get our result! That's why we use another !.
Basically, !! makes us sure the value we get is Boolean, not falsy, truthy, string, etc...
So it's like using the Boolean function in JavaScript, but an easier and shorter way to convert a value to Boolean:
var zero = 0;
!!zero; //false
It simulates the behavior of the Boolean() casting function.
The first NOT returns a Boolean value no matter what operand it is given. The second NOT negates that Boolean value and so gives the true Boolean value of a variable. The end result is the same as using the Boolean() function on a value.
! is "Boolean not", which essentially typecasts the value of "enable" to its boolean opposite. The second ! flips this value. So, !!enable means "not not enable," giving you the value of enable as a Boolean.
I think worth mentioning is that a condition combined with logical AND/OR will not return a Boolean value, but the last success or first fail in case of && and the first success or last fail in case of || of the condition chain.
res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'
In order to cast the condition to a true Boolean literal we can use the double negation:
res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
The !! construct is a simple way of turning any JavaScript expression into
its Boolean equivalent.
For example: !!"he shot me down" === true and !!0 === false.
It's not a single operator; it's two. It's equivalent to the following and is a quick way to cast a value to Boolean.
val.enabled = !(!enable);
It forces all things to Boolean.
For example:
console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false
console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true
console.log(0 === false); // -> false
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
This question has been answered quite thoroughly, but I'd like to add an answer that I hope is as simplified as possible, making the meaning of !! as simple to grasp as can be.
Because JavaScript has what are called "truthy" and "falsy" values, there are expressions that when evaluated in other expressions will result in a true or false condition, even though the value or expression being examined is not actually true or false.
For instance:
if (document.getElementById('myElement')) {
// Code block
}
If that element does in fact exist, the expression will evaluate as true, and the code block will be executed.
However:
if (document.getElementById('myElement') == true) {
// Code block
}
...will not result in a true condition, and the code block will not be executed, even if the element does exist.
Why? Because document.getElementById() is a "truthy" expression that will evaluate as true in this if() statement, but it is not an actual Boolean value of true.
The double "not" in this case is quite simple. It is simply two nots back to back.
The first one simply "inverts" the truthy or falsy value, resulting in an actual Boolean type, and then the second one "inverts" it back again to its original state, but now in an actual Boolean value. That way you have consistency:
if (!!document.getElementById('myElement')) {}
and
if (!!document.getElementById('myElement') == true) {}
will both return true, as expected.
I suspect this is a leftover from C++ where people override the ! operator, but not the bool operator.
So to get a negative (or positive) answer in that case, you would first need to use the ! operator to get a Boolean, but if you wanted to check the positive case you would use !!.
The if and while statements and the ? operator use truth values to determine which branch of code to run. For example, zero and NaN numbers and the empty string are false, but other numbers and strings are true. Objects are true, but the undefined value and null are both false.
The double negation operator !! calculates the truth value of a value. It's actually two operators, where !!x means !(!x), and behaves as follows:
If x is a false value, !x is true, and !!x is false.
If x is a true value, !x is false, and !!x is true.
When used at the top level of a Boolean context (if, while, or ?), the !! operator is behaviorally a no-op. For example, if (x) and if (!!x) mean the same thing.
Practical uses
However it has several practical uses.
One use is to lossily compress an object to its truth value, so that your code isn't holding a reference to a big object and keeping it alive. Assigning !!some_big_object to a variable instead of some_big_object lets go of it for the garbage collector. This is useful for cases that produce either an object or a false value such as null or the undefined value, such as browser feature detection.
Another use, which I mentioned in an answer about C's corresponding !! operator, is with "lint" tools that look for common typos and print diagnostics. For example, in both C and JavaScript, a few common typos for Boolean operations produce other behaviors whose output isn't quite as Boolean:
if (a = b) is assignment followed by use of the truth value of b; if (a == b) is an equality comparison.
if (a & b) is a bitwise AND; if (a && b) is a logical AND. 2 & 5 is 0 (a false value); 2 && 5 is true.
The !! operator reassures the lint tool that what you wrote is what you meant: do this operation, then take the truth value of the result.
A third use is to produce logical XOR and logical XNOR. In both C and JavaScript, a && b performs a logical AND (true if both sides are true), and a & b performs a bitwise AND. a || b performs a logical OR (true if at least one are true), and a | b performs a bitwise OR. There's a bitwise XOR (exclusive OR) as a ^ b, but there's no built-in operator for logical XOR (true if exactly one side is true). You might, for example, want to allow the user to enter text in exactly one of two fields. What you can do is convert each to a truth value and compare them: !!x !== !!y.
I just wanted to add that
if(variableThing){
// do something
}
is the same as
if(!!variableThing){
// do something
}
But this can be an issue when something is undefined.
// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};
// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar
a.foo
b.foo.bar
// This works -- these return undefined
a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar
The trick here is the chain of &&s will return the first falsey value it finds -- and this can be fed to an if statement etc. So if b.foo is undefined, it will return undefined and skip the b.foo.bar statement, and we get no error.
The above return undefined but if you have an empty string, false, null, 0, undefined those values will return and soon as we encounter them in the chain -- [] and {} are both "truthy" and we will continue down the so-called "&& chain" to the next value to the right.
P.S. Another way of doing the above (b && b.foo) is (b || {}).foo. Those are equivalent, because if b is undefined then b || {} will be {}, and you'll be accessing a value in an empty object (no error) instead of trying to access a value within "undefined" (causes an error).
So, (b || {}).foo is the same as b && b.foo and ((b || {}).foo || {}).bar is the same as b && b.foo && b.foo.bar.
It is double Boolean negation. It is often used to check if a value is not undefined.
!!x is shorthand for Boolean(x).
The first bang forces the JavaScript engine to run Boolean(x), but it also has the side effect of inverting the value. So the second bang undoes the side effect.
There are tons of great answers here, but if you've read down this far, this helped me to 'get it'. Open the console in Chrome (etc.), and start typing:
!(!(1))
!(!(0))
!(!('truthy'))
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc., etc., until the light goes on ;)
Naturally, these are all the same as merely typing !!someThing, but the added parentheses might help make it more understandable.
After seeing all these great answers, I would like to add another reason for using !!. Currently I'm working in Angular 2-4 (TypeScript) and I want to return a Boolean as false when my user is not authenticated. If he isn't authenticated, the token-string would be null or "". I can do this by using the next block of code:
public isAuthenticated(): boolean {
return !!this.getToken();
}
It returns the Boolean value of a variable.
Instead, the Boolean class can be used.
(Please read the code descriptions.)
var X = "test"; // The X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value because non-empty strings evaluates as `true` in Boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // Writes `true`
Namely, Boolean(X) = !!X in use.
Please check code snippet out below ↓
let a = 0
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a) // Writes '0 is NOT true in Boolean' value as Boolean - so that's true. In Boolean, 0 means false and 1 means true.
console.log("!!a: ", !!a) // Writes 0 value in Boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // Equals `!!a`
console.log("\n") // Newline
a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes 1 value in Boolean
console.log("\n") // Newline
a = ""
console.log("a: ", a)
console.log("!a: ", !a) // Writes '"" is NOT true in Boolean' value as Boolean - so that's true. In Boolean, empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // Writes "" value in Boolean
console.log("\n") // Newline
a = "test"
console.log("a: ", a) // Writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // Writes "test" value in Boolean
console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
It is important to remember the evaluations to true and false in JavaScript:
Everything with a "Value" is true (namely truthy), for example:
101,
3.1415,
-11,
"Lucky Brain",
new Object()
and, of course, true
Everything without a "Value" is false (namely falsy), for example:
0,
-0,
"" (empty string),
undefined,
null,
NaN (not a number)
and, of course, false
Applying the "logical not" operator (!) evaluates the operand, converting it to boolean and then negating it. Applying it twice will negate the negation, effectively converting the value to boolean. Not applying the operator will just be a regular assignment of the exact value. Examples:
var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23
var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
value2 = value; assigns the exact object value even if it is not boolean hence value2 won't necessarily end up being boolean.
value2 = !!value; assigns a guaranteed boolean as the result of the double negation of the operand value and it is equivalent to the following but much shorter and readable:
if (value) {
value2 = true;
} else {
value2 = false;
}
Here is a piece of code from AngularJS:
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame ||
$window.mozRequestAnimationFrame;
var rafSupported = !!requestAnimationFrame;
Their intention is to set rafSupported to true or false based on the availability of function in requestAnimationFrame.
It can be achieved by checking in the following way in general:
if(typeof requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;
The short way could be using !!
rafSupported = !!requestAnimationFrame;
So if requestAnimationFrame was assigned a function then !requestAnimationFrame would be false and one more ! of it would be true.
If requestAnimationFrame was assigned undefined then !requestAnimationFrame would be true and one more ! of it would be false.
Use the logical not operator two times.
It means !true = false and !!true = true.