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:



6 Comments
Andrea Giammarchi
@zachleat eqeq there ... if (new MyBoolean(false) == false) console.log('????');
Zach Leatherman :11ty:
@webreflection worth a mention in the post, for sure. I don’t have control over all of the contexts in which the code will be used though ????
Mike Aparicio
I mean, who doesn't?
Zach Leatherman
almost everyone that has read this blog post ????
Zach Leatherman :11ty:
@webreflection maybe a little hard to explain on text but given an arbitrary deeply nested object, I want to add metadata to each property that stores an arbitrary string for that property. the approach I’m using is to convert (for boolean types) primitive booleans to object bool… Truncated
vrugtehagel
@zachleat it's not possible - see https://mastodon.social/@vrugtehagel/115308994476955114 If you want to have metadata for properties, you're probably best off wrapping them with a proxy and using a mechanism (like a prefix or named symbols) to look up the metadata witho… Truncated