rabbit.aaron
rabbit.aaron

Reputation: 2579

Comparing to Boolean / boolean in javascript

Should you use == or === to compare with Boolean / boolean values in js? Problem is:

> true == new Boolean(true)
< true
> true === new Boolean(true)
< false

same goes for String:

> 'foo' == new String('foo')
< true
> 'foo' === new String('foo')
< false

I understand that this is happening because String and Boolean are objects whereas true, false and 'string' are literals.

function foo(bar){
  /* if statement here{ 
    I want the code between these two lines to execute when and only when foo is true,
    or new Boolean(true), which operator to use?
  } */

}

Upvotes: 0

Views: 3238

Answers (3)

rabbit.aaron
rabbit.aaron

Reputation: 2579

I came up with this solution.

function typeOf(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1);
}

function foo(bar){
  if((typeOf(bar) === 'Boolean' && bar.valueOf() === true) || bar === true){
     // is this perfect though ?
  }
}



> Object.prototype.toString.call(true)
< "[object Boolean]"
> Object.prototype.toString.call(false)
< "[object Boolean]"
> Object.prototype.toString.call(Boolean(true))
< "[object Boolean]"
> Object.prototype.toString.call(Boolean(false))
< "[object Boolean]"
> Object.prototype.toString.call(new Boolean(true))
< "[object Boolean]"
> Object.prototype.toString.call(new Boolean(false))
< "[object Boolean]"
> Object.prototype.toString.call(undefined)
< "[object Undefined]"
> Object.prototype.toString.call(null)
< "[object Null]"
> Object.prototype.toString.call(1)
< "[object Number]"

Upvotes: 0

p.s.w.g
p.s.w.g

Reputation: 149000

You might try using the valueOf method to get the underlying value of a wrapped Boolean:

function isTrue(b) { 
   return b.valueOf() === true; 
}

isTrue(true);                      // true
isTrue(new Boolean(true));         // true
isTrue(false);                     // false
isTrue(new Boolean(false));        // false
isTrue("true");                    // false

However, I should note that it's possible to override this function for custom types or even for built-in types, for example:

Boolean.prototype.valueOf = function () { return true; }; 
isTrue(false);                     // true

Also note, this simple example doesn't handle null or undefined values.

In general though, I wouldn't use this kind of method for general purpose parameter validation in a library. I think it's fairly safe to assume that if a user passes in a new Boolean(true) they probably have a specific reason for doing so (or as Barmar says, it's a bug in their code).

Upvotes: 1

Claudia
Claudia

Reputation: 1269

Generally, if you know you're dealing with the object variants, then it is better, in both performance and readability's sake, to stick with .valueOf() === some_boolean than using non-strict equals. Example:

var b = new Boolean(true);
b.valueOf() === true; // true

It is typically better to avoid Boolean objects without a specific reason, because it leads to bugs very quickly because of that confusion. It also results in leaner, faster code when it matters.

var b = new Boolean(foo);

// ...

if (!b) {
  // This always executes, leading to some impossibly hidden bugs.
}

Upvotes: 0

Related Questions