The Dom Boundary And Automatic Coercion
Type coercion is not a mistake: it's a design feature built for the flexibility of the web browser.
Now that we've seen how closure allows our functions to keep their memories, we're ready to tackle the "dark side" of JavaScript. Its type coercion is often called "notorious" or "infamous," but it's actually an incredibly powerful system designed to be flexible.
JavaScript doesn't run in isolation; it runs in a web browser. In the early days, its designers thought, "Let's be helpful here and coerce data types to make them usable immediately."
The Essentials
- Operators as Action Dispatchers: Operators like
*or+aren't just symbols; they kick off actions (like multiplication or coercion) based on the operands adjacent to them. - The DOM Boundary: Data flying from the webpage (DOM) into JavaScript almost always arrives as a string, even if the user typed a number.
- Coercion Funnels: JavaScript uses three major funnels to convert data:
toNumber,toString, andtoBoolean.
The Webpage Boundary
Imagine we're building a product page. We have a price of 7 and a quantity that the user enters into a form.
let price = 7;
let quantity = "3"; // Comes from the DOM as a string
let total = price * quantity;In any other language, multiplying a number by a string (a letter "3") would be an error. You can't multiply a number by a letter. But JavaScript's designers wanted to make the interface between the DOM and the runtime less strenuous.
The toNumber Funnel
As soon as the multiplication operator (*) sees a number on one side and a string on the other, it kicks off type coercion. It hits the string with a toNumber conversion, turning the string "3" into the number 3.
Step 1:Global memory stores the number 7.
The "Mortifying" Result: The + Operator
While most math operators (-, *, /) always kick off toNumber, the addition operator (+) is a bit of a "trickster."
If you have a donation of "10" (from a string) and you try to add it to your total of 21:
let total = 21;
let donation = "10";
let grandTotal = total + donation; // "2110"Because one side of the + is a string, JavaScript kicks off the toString funnel instead of toNumber. It converts the number 21 into the string "21", and then concatenates the two strings.
The result is "2110". This is a fairly mortifying result that gives programming languages a bad name, but it's a consequence of the design decision to favor string concatenation when a string is present.
Taking Manual Control
To avoid these unpredictable automated behaviors, pro-code developers take manual control of coercion. Instead of letting the operator decide, we manually trigger the conversion:
- Unary Plus:
+quantitymanually kicks offtoNumber. - Number Function:
Number(quantity)manually kicks offtoNumber. - Template Literals:
`${total}`manually kicks offtoString.
By being explicit at the browser boundary, we ensure our code remains predictable and bug-resistant.
In the next part, we'll look at the "comparison problem" and why identical-looking objects can be so hard to match.
Further Reading and Watching
- Video: Type Coercion and the DOM Boundary
- MDN: Type Coercion
- Concept: Operators and Operands
Keep reading