admin管理员组文章数量:1425666
I know ==
operator performs the type coercion. But I can't understand the below behaviour.
const x = new Boolean(false);
if (x) {
console.log("if(x) is true");
}
if (x == false) {
console.log("if(x == false) is true");
}
I know ==
operator performs the type coercion. But I can't understand the below behaviour.
const x = new Boolean(false);
if (x) {
console.log("if(x) is true");
}
if (x == false) {
console.log("if(x == false) is true");
}
Surprisingly, above snippet prints both lines:
if(x) is true
if(x == false) is true
Can someone explain this weird behaviour or there is something fundamental I'm missing?
Share Improve this question edited Feb 15, 2019 at 23:46 jo_va 14k3 gold badges25 silver badges49 bronze badges asked Feb 15, 2019 at 23:44 Varinder SinghVarinder Singh 1,6001 gold badge11 silver badges27 bronze badges 3- @JohnMontgomery Then why statement evaluates to true – Varinder Singh Commented Feb 15, 2019 at 23:48
-
1
This isn't a type coercion thing, this is a boxing thing. This is exactly why you don't do
new Boolean()
ornew Number()
ornew String()
. – Madara's Ghost Commented Feb 15, 2019 at 23:53 - Please refer to the following documentation from the well-versed Kyle Simpson about Falsy Objects. I actually suggest you read the whole book that is there for free. – Chris Tapay Commented Feb 16, 2019 at 0:00
5 Answers
Reset to default 4As mentioned by other answers, that's because x
is an Object – a Boolean object, but still an object, since you're using the new
operator – and is coerced only when you pare x
to false
: the if (x)
is checking if x
is a truthy value, and therefore doesn't need coercion (there are no other operands involved): an object is always "true" (weeeell… almost always: typeof null
returns object
but it's a falsy value. But that's another story…).
You can easily checking when the coercion is invoked tapping the toPrimitive symbol:
var x = new Boolean(false);
// first of all, if it wasn't an object you couldn't
// do this
x[Symbol.toPrimitive] = function(hint) {
console.log({hint});
return this.valueOf();
}
// no console.log yet
if (x) {
console.log("if(x) is true");
}
// here you got the console.log before the one
// inside the block, since the coercion happens
// in the `if`
if (x == false) {
console.log("if(x == false) is true");
}
new Boolean(false)
produces an object. Objects are always truthy even if they wrap a falsy primitive value. For example, new String("")
is also truthy despite ""
being falsy.
On the other hand, when you do new Boolean(false) == false
, it coerces the object to its primitive value for the parison. Incidentally, new Boolean(false) === false
is not true, since their types don't match.
As a general rule, you shouldn't use object constructors for primitive types unless you have a specific reason for it, to avoid unexpected behavior like this.
when you do if (expression)
in javascript the expression is evaluated by being cast to a boolean.
Somewhat confusingly, Boolean(new Boolean(false))
evaluates to true because as Nick said it is still an object. This is what is causing the behaviour you're confused about.
Good read for more info https://javascriptweblog.wordpress./2011/02/07/truth-equality-and-javascript/
If you write
const x = new Boolean(false);
typeof x
will return object
. The type object
is "truthy", which means it evaluates to true if there's no operator like ==
. However, the value of it is false
, which is why the second statement evaluates to true as well.
So the if
statements behave differently, because the if
without operator checks whether the type is truthy or falsy (in this case truthy -> true) and the if with the parison (==) calls .valueOf()
which is false
.
You shouldn't be using new
wrappers for this scenario anyway.
const x = false;
is enough. For casting, you can use Boolean()
without new
wrapper.
To check whether a value is truthy, you can use a double negation:
const x = new Boolean(false);
if (x) console.log(!!x);
if (x == false) console.log(x.valueOf());
You should be using Boolean(false)
instead of new Boolean(false)
, since Boolean
is a function.
Otherwise you get an empty object {}
, which is not the same type as what is returned by the function itself, which is a boolean
.
const x = new Boolean(false);
const y = Boolean(false);
console.log(x, typeof x);
console.log(y, typeof y);
In the your first test, you only check if the value is truthy, and an empty object is truthy, since x = {}
, the test passes:
const x = new Boolean(false);
console.log(x, !!x, !!{}, Boolean(x))
if (x) {
console.log("if(x) is true");
}
However, when using ==
, the operator coerces new Boolean(false)
to its primitive value using x.valueOf
which is false
and thus the equality passes.
const x = new Boolean(false);
console.log(x.valueOf())
本文标签: nodejsUnderstanding type coercion in JavaScriptStack Overflow
版权声明:本文标题:node.js - Understanding type coercion in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745447849a2658744.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论