0

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?
  } */

}

8
  • 2
    There's no good reason to ever use new Boolean(). These objects don't act like booleans. new Boolean(false) is truthy. Commented Sep 9, 2014 at 1:06
  • 1
    In addition to @Barmar, there is very few circumstances where x == true is needed. If you are checking for truthiness, x suffices; if you want to see if it's exactly true, you need to write x === true. Commented Sep 9, 2014 at 1:10
  • @Amadan My point is that x doesn't work at all if you use new Boolean, since both new Boolean(true) and new Boolean(false) are truthy. Commented Sep 9, 2014 at 1:18
  • @Barmar: I was agreeing with you. I guess I wasn't clear. 1) Don't use Boolean, 2) if you use primitive boolean, don't use x == true. Commented Sep 9, 2014 at 1:19
  • @p.s.w.g typeof bar === "boolean" && bar isn't it the same as bar === true ?? Commented Sep 9, 2014 at 1:34

3 Answers 3

1

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Your Number.p.valueOf example is meaningless, because 123 is truthy to begin with. I suggested an edit to fix that nit.
@impinball It's not meaningless. Without overriding the method, isTrue(123)false. Remember, this method doesn't test if a b is truthy, it tests if its primitive value exactly equals true.
@pswg I still left my edit because it also mentions truthiness/falsiness, which can also come into play.
@impinball Thanks, I've edited to provide an even more clear example of how this method can be subverted.
0

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.
}

Comments

0

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]"

1 Comment

I just realize I could have just do bar.valueOf() === true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.