If you've ever stared at someone else's JavaScript code and wondered why they sometimes write `obj.name` and other times write `obj["name"]`, you're not alone. Bracket and dot notation both access the same data, yet each has situations where one shines and the other just won't work. Understanding the difference matters more than most tutorials suggest, especially when you're building the kind of interactive features that power modern web applications.
According to genicsblog.com, objects in JavaScript store data as key-value pairs, and how you reach that data changes what you can do with it. Let's break this down so you know exactly which notation to reach for in your next project.
What happened
- Dot notation works when you know the exact property name at write time
- Bracket notation accepts dynamic keys loaded from variables or user input
- Numbers used as keys get converted to strings automatically
- Reserved words like "return" can become property names without issues
- The `delete` keyword removes properties, and `in` checks whether they exist
When Dot Notation Just Works
Think of dot notation as the quick-dial option on your phone. You've got a specific contact you call all the time, so you want the shortest path to reach them.
“`javascript
Let user = { name: "Sarah", age: 30, isAdmin: false };
Console.log(user.name); // Sarah
“`
You can add new properties the same way. If you need to extend an object at runtime, you just write `user.newProperty = "value"` and it's there. Deleting works the same way: `delete user.isAdmin` removes that property instantly.
The limitation? Dot notation demands you know the exact property name when you're writing the code. If the property name lives in a variable or comes from user input, dot notation can't help you.
When You Need Bracket Notation
Bracket notation is like using your phone's search function. You don't have the contact saved under a specific name—you're looking up whoever matches what you type in the moment.
“`javascript
Let products = { laptop: "premium", phone: "budget" };
Let search = "laptop";
Console.log(products[search]); // premium
“`
Here, `search` holds the property name. The code reads whatever's inside the brackets and uses that string to find the matching key. This becomes essential when keys come from:
- User input or form fields
- API responses you didn't write
- Loops where the property name changes each iteration
- Configuration files or environment variables
You can also define objects with computed property names using brackets at declaration time. If you want the key itself to be dynamic—say, based on what a user selects from a dropdown—you wrap it in square brackets when creating the object.
A Practical Scenario
Say you're building a sprint dashboard. Your team tracks velocity metrics, and the product owner wants to filter views based on which sprint is currently active.
“`javascript
Let sprintData = {
"sprint-1": { completed: "high", status: "active" },
"sprint-2": { completed: "low", status: "planning" }
};
Let selectedSprint = "sprint-2"; // could come from a button click
Console.log(sprintData[selectedSprint].status); // outputs planning status
“`
With dot notation, you'd need separate code for each sprint. With bracket notation, one line handles whatever sprint your user selects. The `selectedSprint` variable could come from a dropdown, a URL parameter, or a button click—your code doesn't need to change. The key insight is that the data structure stays the same; only the lookup mechanism becomes flexible.
Our Analysis
For most everyday object access, dot notation wins on readability. `user.name` is instantly clearer than `user["name"]`. But readability shouldn't trump flexibility—when your property names vary, bracket notation is non-negotiable.
The irony is that many developers default to one notation exclusively. Those who love dot notation sometimes write convoluted workarounds to avoid brackets. Those who prefer brackets sometimes miss opportunities for cleaner code.
The real skill is knowing which situation you're in before you start typing. Ask yourself: do I know this property name right now, or will I only know it when the code runs? That one question tells you which tool to reach for.
One thing the reference doesn't explicitly mention but worth noting: both notations are interchangeable for static property names. You can write `obj.name` or `obj["name"]` and get identical results. Choose based on context, not correctness.
What to Watch Next
Bookmark the distinction between static and dynamic keys. Once that distinction clicks, you'll stop second-guessing your own code. Try refactoring a past project—swap dot notation for brackets where keys could be variables and see what becomes possible.
—
Key takeaways
- Use dot notation when property names are known at write time; use bracket notation when they arrive at runtime
- Bracket notation enables dynamic feature flags, dashboard filters, and user-driven views
- Both notations share the same underlying object—changes in one reflect in the other
- Numbers used as keys get converted to strings, so `obj[0]` and `obj["0"]` access the same property
- Test your assumptions: if you ever need to look up a property name rather than write it, switch to brackets
Frequently asked questions
Can I mix dot and bracket notation on the same object?
Yes. You can access some properties with dot notation and others with brackets within the same object, depending on what each property requires.
Does bracket notation work with nested objects?
Absolutely. You can chain them like `obj.level1["level2"].name` or combine styles like `obj.level1.level2["name"]`.
What's the performance difference between the two notations?
For practical purposes, none worth worrying about. The difference only matters in tight loops running millions of iterations.
Can property names include spaces or special characters?
Only with bracket notation. `obj["first name"]` works, but `obj.first name` causes a syntax error. Dot notation requires valid identifier names.
How do I check if a property exists before accessing it?
Use the `in` operator: `"name" in user` returns true if the property exists, false otherwise. Accessing a missing property returns `undefined` rather than throwing an error.