I want to intercept Boolean Coercion for Objects in JavaScript
MDN takes a strong stance against using new
with Boolean
:
…all objects, including a Boolean object whose wrapped value is false, are truthy and evaluate to true in places such as conditional statements. — MDN: Boolean: Boolean primitives and Boolean objects
(…though it makes use of it on other pages without a warning)
!!(Boolean(false)) // false
// Don’t use this!
!!(new Boolean(false)) // true
A quick shout out to previously unknown (to me) new.target
for detecting use of new
in your own classes.
But how do I customize this behavior? I want to make my own Boolean-esque object and I need a low-level mechanism to intercept boolean primitive coercion to do it!
Consider this class that extends Boolean
:
class MyBoolean extends Boolean {
[Symbol.toPrimitive]() {
return this.valueOf();
}
}
!!(new MyBoolean(true)) // true
!!(new MyBoolean(false)) // true (I want `false`)
Or this example creating a new Boolean-esque class:
class MyBoolean {
#v;
constructor(val) {
this.#v = Boolean(val);
}
// not triggered
valueOf() {
return this.#v;
}
// not triggered
[Symbol.toPrimitive]() {
return this.#v;
}
}
!!(new MyBoolean(true)) // true
!!(new MyBoolean(false)) // true (I want `false`)
MDN again, with a quick quip:
Note: Unlike other type conversions like string coercion or number coercion, boolean coercion does not attempt to convert objects to primitives by calling user methods.—MDN: Boolean: Boolean coercion
I wish I could end this blog post with some magical hack that I found to workaround this behavior, but I have yet to make such a discovery. I’m only left with this blog-post-as-comment-card hoping that someone will see my plea to unlock this new power. ECMAScriptarians, help!
Related: