JavaScript's Surprising Sides: Type Coercion, Event Loop, and Floating Point Precision

Welcome to the fourth edition of this weekly series where we look at the surprising sides of programming languages. Even in times where a growing share of code is generated by AI tools, understanding how a language works under the hood remains both fun and relevant. Knowing why a language behaves the way it does helps you read, debug, and reason about code with confidence. This week we look at JavaScript. JavaScript performs automatic type coercion when operators work on values of different types, silently converting operands so the operation can proceed. The plus operator behaves differently depending on its inputs: if one operand is a string, JavaScript converts the other to a string and concatenates, so 5 + "3" yields 53 instead of 8 or a type error. Subtraction instead converts both operands to numbers, so 5 - 3 is 2. The conversion rules are precisely defined in the specification but complex enough to surprise even experienced developers with edge cases like [] + [] resulting in an empty string or [] + {} resulting in [object Object]. The strict equality operator === was introduced later to help developers avoid unintended coercion. The next concept is the event loop. JavaScript is single-threaded, so it runs one piece of code at a time but still manages asynchronous tasks like network requests, timers, and user input without blocking. It does this through the event loop, which checks if the call stack is empty and then pulls the next task from a queue. When you call setTimeout with a zero delay, its callback goes into the task queue and runs only after the current stack clears, so it executes after subsequent synchronous code. Promises add another layer with a microtask queue, which has higher priority than the regular task queue. Knowing this distinction is key to predicting execution order in asynchronous JavaScript. In JavaScript, all numbers are 64-bit floating point values following the IEEE 754 standard, and there is no separate integer type. As a result, 0.1 + 0.2 does not equal 0.3 but instead yields 0.30000000000000004, not because of a JavaScript bug but due to how binary floating point represents decimal fractions. The value 0.1 cannot be represented exactly in binary, just as one third cannot be written exactly in decimal. This issue affects any language using IEEE 754, but it is more visible in JavaScript because there is no integer type to fall back on for exact whole-number arithmetic. For financial or precision-critical work, developers typically use libraries for arbitrary-precision arithmetic or operate on integers representing the smallest unit, such as cents instead of dollars. Next week, we continue with a different language. #JavaScript #JS #Programming #SoftwareEngineering #CodeCuriosities #DevCommunity

  • No alternative text description for this image

To view or add a comment, sign in

Explore content categories