Reputation: 2579
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
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
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
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