When most aspiring developers are learning, whether in a data structures course or exploring a new programming language, our natural instinct is to figure out: what is this, and how does it work? That's a solid start. For the longest time, this has been exactly how I approached new concepts up until recently.
In the software development world, there are various tools that solve the same problems, such as different frameworks, languages, or even entire stacks that all build similar apps. For instance, Java and C++ share many core programming principles. So when developers make architectural choices—say, choosing React over Vue or PostgreSQL over MongoDB—we're often forced to ask the deeper question: "Why this approach over another?" It hit me that we shouldn't wait until project decision-making to ask "why." We should be asking it as we learn alongside the "what."
The Power of Understanding Why
Understanding why something exists gives you a level of clarity that goes beyond memorization:
- It shows you the problem the concept or tool was designed to solve.
- It reveals the trade-offs and limitations baked into the design.
- It helps build intuition, making it easier to pick the right tool later—even if it's one you've never used.
- It reinforces transferable knowledge instead of siloed facts.
A Practical Example: JavaScript Hoisting
Recently, I was trying to brush up on Javascript basics and approached the topic: What is hoisting? Hoisting in JavaScript is JavaScript's default behavior of moving declarations to the top. But then I asked myself a subtle but important question because I couldn't see it in the moment: why does JavaScript even have hoisting in the first place?
By asking this simple question, I learned that Hoisting exists in JavaScript because of how the language was originally designed to be interpreted and executed.
JavaScript engines read and parse code in two phases:
- Parsing Phase: The engine scans the code for declarations (like var and function) and adds them to memory.
- Execution Phase: The engine runs the code line by line.
To make code more forgiving and reduce errors from calling functions or referencing variables before they're defined, JavaScript "hoists" declarations to the top of their scope during the parsing phase. This means:
- Functions can be called before they appear in the code.
- Variables declared with var exist from the top of their scope, though they're initially set to undefined.
This design choice was made to allow flexible, top-down coding and to enable things like mutual recursion or separating logic and declarations without needing to rearrange code order manually.
From Memorization to Understanding
What felt like a simple concept suddenly had a purpose. And by understanding that purpose, I wasn't just memorizing behavior—I was internalizing how the language thinks.
That one moment helped me realize that even the smallest concepts can unlock deeper understanding when you lead with why. You not only avoid hype-driven choices but also make more strategic decisions in your own project architecture.