Why logical not operator in javascript returns different result between Boolean value and Boolean object? Consider the following example.
!true // false !false // true !(new Boolean(true)) // false !(new Boolean(false)) // false
From the spec, it says that the value being evaluated converted ToBoolean
. ToBoolean will return true if the argument is an Object, and return as is if the argument is a Boolean.
Digging further, ToBoolean also being used in other places like if statement and conditional operator, consider the following example:
var a = (new Boolean(false)) ? "unexpected" : "expected"; console.log(a); // unexpected
The question: is Boolean object an Object, or a Boolean? Should we not evaluate Boolean object as a Boolean?
UPDATE
My question was marked as duplicate question with this. That question doesn't have a satisfactory answers because none answers my question, Is Boolean object an Object, or a Boolean? Should we not evaluate Boolean object as a Boolean?
Simply knowing Boolean object is an object is not enough, why does it even exists and what is the proper way of dealing and/or designing objects with Boolean object still left unanswered.
Logical operators take boolean operands and return a boolean result. The operands for logical operators can be: expressions using relational operators.
Javascript doesn't care about missing method parameters to begin with. You are setting the default value of the method parameter to the default value of a boolean (i.e. false )
There are only two boolean values. They are True and False . Capitalization is important, since true and false are not boolean values (remember Python is case sensitive).
The logical OR ( || ) operator (logical disjunction) for a set of operands is true if and only if one or more of its operands is true. It is typically used with boolean (logical) values. When it is, it returns a Boolean value.
Boolean
is a function. Depending on the invocation type, it has different behavior in terms of truthy
and falsy
.
1. Invoking as a simple function
When calling Boolean(value)
as a simple function, it verifies if the argument is a falsy
(false
, null
, undefined
, ''
, 0
,Nan
) or truthy
(all other values: object instances, 1
, true
, etc). This type of invocation returns a boolean primitive type.
It works as expected:
Boolean(null) // prints false Boolean(0) // prints false Boolean({}) // prints true Boolean(-1) // prints true
2. Invoking as a constructor
Like any function in JavaScript, Boolean
can be invoked as a constructor: var b = new Boolean(value)
. This invocation type returns a boolean object instance.
This introduces confusing because JavaScript treats object instances as truthy
value.
var b = new Boolean(null); !!b // prints true, because b is an object instance if (b) { // b evaluates to true //executed code }
2.1 Why invoking as a constructor is possible
JavaScript allows this constructor invocation to give developer a mechanism to preserve properties creation for a boolean
. A primitive boolean type doesn't save properties assigned to it.
var booleanObject = new Boolean(null); booleanObject.foo = 'bar'; // create a property booleanObject.foo // prints 'bar' var booleanPrimitive = false; booleanPrimitive.foo = 'bar'; // create a property booleanPrimitive.foo // prints undefined
2.2 How to make the Boolean object work
Nevertheless, new Boolean(value)
has a mechanism to do comparison. Like any JavaScript object, it has a method valueOf()
, which returns the transformation of the value
to a boolean primitive type (true
for truthy and false
for falsy):
var falsyBoolean = new Boolean(null); falsyBoolean.valueOf() // prints false, because null is falsy var truthyBoolean = new Boolean(1); truthyBoolean.valueOf() // prints true, because 1 is truthy
To make this work in conditionals, it is necessary to avoid any transformations of the boolean object instance into a truthy value. To make this happen, use comparison operator ==
directly:
var falsyBoolean = new Boolean(null); falsyBoolean == false ? 'falsy' : 'truthy' // prints expected 'falsy' if (falsyBoolean == false) { //executed code }
If an operand in ==
operator is an object and other a primitive type, JavaScript transforms it into a primitive type, which actually consists in calling the valueOf()
method on the boolean object. See more details in this article.
3. How not to get confused
The best rule is to avoid using Boolean
as object instances at all. Boolean(value)
or !!value
is enough to verify the variable truthy state.
An
object
, no matter if it has properties or not, never defaults tofalse
...
new Boolean(true)
will return an object
not Boolean
and !{}
is always going to be false
as {}
is a truthy
value (Boolean({})
will be evaluated as true
)
While dealing with Boolean
factory function, do not create new instance using new
(as it will create new instance of Boolean
and will return an object
)
Boolean(INPUT)
will return primitive-Boolean
value of the specified expression
which could be used for comparison
From docs, The Boolean object is an object wrapper for a boolean value
()
Description: The value passed as the first parameter is converted to a
boolean
value, if necessary. If value is omitted or is0, -0, null, false, NaN, undefined, or the empty string ("")
, the object has an initial value offalse
. All other values, including any object or the string "false", create an object with an initial value oftrue
.
Do not confuse the primitive Boolean values true and false with the true and false values of the Boolean object.
Any object whose value is not undefined
or null
, including a Boolean object
whose value is false, evaluates to true
"when passed to a conditional statement."[Reference]
For example, the condition in the following if statement evaluates to true
var x = new Boolean("false"); if (x) { console.log('x is true'); } var y = new Boolean(false); if (y) { console.log('y is true'); }
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With