Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logical NOT on Boolean Object always return false in Javascript [duplicate]

Tags:

javascript

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.

like image 763
O.O Avatar asked Apr 19 '16 05:04

O.O


People also ask

Do logical operators return a boolean result?

Logical operators take boolean operands and return a boolean result. The operands for logical operators can be: expressions using relational operators.

Do booleans default to false JavaScript?

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 )

Which of the value is not a boolean 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).

Which JavaScript operators will return a boolean value?

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.


2 Answers

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.

like image 31
Dmitri Pavlutin Avatar answered Sep 28 '22 09:09

Dmitri Pavlutin


An object, no matter if it has properties or not, never defaults to false...

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 is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false. All other values, including any object or the string "false", create an object with an initial value of true.

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>
like image 90
Rayon Avatar answered Sep 28 '22 08:09

Rayon