Problem
I’m not an expert in Javascript, but I was reading Mark Pilgrim’s “Dive into HTML5” webpage and he stated something that I’d like to learn more about.
He states:
function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
I’d appreciate it if someone could explain this to me a little clearer!
Asked by ProfessionalAmateur
Solution #1
There is a logical NOT operator! transforms a value to a boolean that is the logical inverse of the value.
The second! returns the preceding boolean result to its original logical value’s boolean form.
The following is taken from the documentation for the Logical NOT operator:
As a result, if getContext returns a “falsey” value, the!! will force it to return the boolean value false. Otherwise, true will be returned.
The “falsey” values are as follows:
Answered by user113716
Solution #2
When used in a setting where a Boolean is anticipated, Javascript has a complicated set of rules for what is considered “true” and “false.” However, the logical-NOT operator,!, always yields a valid Boolean value (one of the constants true and false). The idiom!!expression creates a valid Boolean with the same truthiness as the original expression by chaining two of them.
What’s the point of bothering? Because it improves the predictability of functions like the one you’ve shown. It may return undefined, a Function object, or anything similar to a Function object if the double negative wasn’t present. The entire code may malfunction if the caller of this function does something strange with the return value (“weird” here means “anything but an operation that enforces Boolean context”). This is prevented by the double-negative idiom.
Answered by zwol
Solution #3
The “bang” operator (!) in javascript returns true if the specified value is true, 1, not null, and so on. If the value is undefined, null, 0, or an empty string, it will return false.
As a result, the bang operator will always return a boolean value, but it will be the inverse of what you started with. You can reverse the result of that operation by “banging” it again, but you’ll still end up with a boolean (and not undefined, null, etc).
When you use the bang twice, you’ll get a value that may be undefined, null, or just plain false. It will take a value that may have been 1, “true,” or something else and just make it true.
It’s possible that the following code was written:
var context = document.createElement('canvas').getContext;
var contextDoesNotExist = !context;
var contextExists = !contextDoesNotExist;
return contextExists;
Answered by StriplingWarrior
Solution #4
When you use!!variable, you can be sure that the typecast will be to boolean.
To give you an example, consider the following:
"" == false (is true)
"" === false (is false)
!!"" == false (is true)
!!"" === false (is true)
However, if you’re doing something like this, it’s not a good idea to use it.
var a = ""; // or a = null; or a = undefined ...
if(!!a){
...
The if will cast it to boolean so there is no need to make the implicit double negative cast.
Answered by fmsf
Solution #5
! converts a boolean to “something”/”anything.”
!! restores the boolean value to its original state (and guarantees the expression is a boolean now, regardless to what is was before)
Answered by schnaader
Post is based on https://stackoverflow.com/questions/4686583/can-someone-explain-this-double-negative-trick