JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
191: Building a Simple Calculator UI
I've seen this happen to almost every developer the first time they build a calculator. You've got your buttons laid out, your event listeners are firing, and everything looks great—until you actually try to add two numbers. You hit 2, then +, then 3, and instead of seeing 5, your screen displays 23.
// The "Broken" Logic
let currentInput = "";
let previousInput = "";
let operator = null;
function handleNumber(num) {
currentInput += num; // num comes from button.innerText
updateDisplay(currentInput);
}
function handleOperator(op) {
operator = op;
previousInput = currentInput;
currentInput = "";
}
function calculate() {
if (operator === '+') {
// BUG: "2" + "3" becomes "23"
const result = previousInput + currentInput;
updateDisplay(result);
}
}
Why your calculator is concatenating instead of adding
The issue here is that innerText and value are always strings. In JavaScript, the + operator is overworked; it handles both mathematical addition and string concatenation. When JS sees two strings, it assumes you want to glue them together, not sum them. I used to spend hours debugging this until I realized I was essentially asking the browser to join two pieces of text.
Coercing strings into actual numbers
To fix this, we need to explicitly tell JavaScript that these strings should be treated as numbers before the math happens. While you could use parseInt(), parseFloat() is the safer bet for a calculator because it allows for decimals. If you're feeling modern, the Number() constructor also works well.
function calculate() {
// Convert strings to floats to ensure math, not concatenation
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
if (operator === '+') {
const result = prev + current;
updateDisplay(result);
}
// ... other operators
}
Wiring up the buttons to the display
When building the UI, don't attach a separate event listener to every single button. That's a nightmare to maintain. Instead, use event delegation. Wrap your buttons in a container and listen for clicks at the parent level. You can then use event.target to figure out which button was pressed. It's cleaner and much more efficient.
I usually give my buttons data-attributes (like data-type="number" or data-type="operator"). This allows me to separate the visual label on the button from the logic I'm using in the script.
Managing the calculator state
A calculator is essentially a state machine. You need to track three main things: the value currently being typed, the value that was typed previously, and the operator that connects them. The trickiest part is the "transition"—what happens when the user hits an operator button? You have to move the currentInput into the previousInput slot and clear the screen for the next number, all while remembering which operation was selected. If you don't clear the current input, you'll end up appending the second number to the first one on the screen.
📋 Practical Task
Implementing a "Clear" and "Delete" Functionality
Now that you have the basic calculation logic working, your UI needs a way to recover from mistakes. Your current calculator likely lets users type numbers, but once a number is entered, there's no way to fix a typo without refreshing the page.
Your Task:
- Add two new buttons to your HTML: one labeled "AC" (All Clear) and one labeled "DEL" (Delete).
- Implement a function for "AC" that resets all state variables (
currentInput,previousInput, andoperator) back to their initial empty or null values and clears the display. - Implement a function for "DEL" that removes only the last character from the
currentInputstring using theslice()method and updates the display. - Ensure that if the
currentInputis already empty, clicking "DEL" does nothing.
There are no comments for now.