In JavaScript, you can use dot notation (.
) or bracket notation ([]
) to access object properties. They do the same thing… until they don’t. Then you’ll be googling “why is JavaScript like this”!
Understanding when to use each approach is crucial for writing clean, maintainable, and robust JavaScript code.

The Basics
Dot Notation
Dot notation uses a period followed by the property name to access object properties:
1
2
3
4
5
6
7
8
|
const user = {
name: 'Alice',
age: 30,
email: 'alice@example.com'
};
console.log(user.name); // 'Alice'
console.log(user.age); // 30
|
Bracket Notation
Bracket notation uses square brackets with the property name as a string:
1
2
3
4
5
6
7
8
|
const user = {
name: 'Alice',
age: 30,
email: 'alice@example.com'
};
console.log(user['name']); // 'Alice'
console.log(user['age']); // 30
|
When to Use Dot Notation
Dot notation is the preferred approach in most scenarios due to its clean syntax and better readability. Use dot notation when:
1. Property Names Follow JavaScript Identifier Rules
Property names that are valid JavaScript identifiers (start with letter, underscore, or dollar sign, followed by letters, numbers, underscores, or dollar signs) work perfectly with dot notation:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const product = {
productId: 'ABC123',
price: 29.99,
inStock: true,
_internal: 'hidden',
$special: 'marked'
};
// All these work with dot notation
console.log(product.productId);
console.log(product.price);
console.log(product._internal);
console.log(product.$special);
|
2. You Know the Property Name at Write Time
When you’re writing code and know exactly which property you want to access, dot notation provides the cleanest syntax:
1
2
3
4
5
6
7
|
function getUserInfo(user) {
return {
displayName: user.firstName + ' ' + user.lastName,
contact: user.email,
isActive: user.status === 'active'
};
}
|
3. Better IDE Support
Most code editors and IDEs provide better autocomplete, syntax highlighting, and error detection with dot notation:
1
2
3
|
// IDE can easily suggest properties and catch typos
user.firstName // ✓ Good autocomplete
user.firstNam // IDE might catch this typo
|
When to Use Bracket Notation
Bracket notation becomes necessary or preferable in several specific scenarios:
1. Property Names with Special Characters or Spaces
When property names contain spaces, hyphens, or other special characters that aren’t valid in JavaScript identifiers:
1
2
3
4
5
6
7
8
9
10
11
|
const config = {
'api-key': 'secret123',
'base url': 'https://api.example.com',
'user-agent': 'MyApp/1.0',
'2023-data': 'yearly statistics'
};
// Must use bracket notation
console.log(config['api-key']);
console.log(config['base url']);
console.log(config['2023-data']);
|
2. Dynamic Property Access
When the property name is stored in a variable or computed at runtime:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const user = {
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com'
};
// Dynamic property access
const propertyName = 'firstName';
console.log(user[propertyName]); // 'John'
// Computed property names
const fields = ['firstName', 'lastName', 'email'];
fields.forEach(field => {
console.log(`${field}: ${user[field]}`);
});
|
3. Property Names Starting with Numbers
JavaScript identifiers cannot start with numbers, so bracket notation is required:
1
2
3
4
5
6
7
8
9
10
|
const stats = {
'1stQuarter': 25000,
'2ndQuarter': 30000,
'3rdQuarter': 28000,
'4thQuarter': 35000
};
// Must use bracket notation
console.log(stats['1stQuarter']);
console.log(stats['2ndQuarter']);
|
4. Programmatic Property Access
When building generic functions that work with various object properties:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function getNestedProperty(obj, path) {
return path.split('.').reduce((current, property) => {
return current ? current[property] : undefined;
}, obj);
}
const user = {
profile: {
personal: {
name: 'Alice'
}
}
};
console.log(getNestedProperty(user, 'profile.personal.name')); // 'Alice'
|
5. Property Names from External Sources
When property names come from user input, API responses, or configuration files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// API response might have dynamic field names
const apiResponse = {
'user-id': 123,
'created-at': '2023-01-15',
'last-login': '2023-07-30'
};
// Configuration-driven property access
const fieldsToExtract = ['user-id', 'created-at'];
const extractedData = {};
fieldsToExtract.forEach(field => {
extractedData[field] = apiResponse[field];
});
|
Both dot and bracket notation have similar performance characteristics in modern JavaScript engines. However, there are subtle differences:
1
2
|
// Slightly faster due to compile-time optimization
const value = obj.property;
|
1
2
3
4
5
6
|
// Minimal overhead for string literals
const value = obj['property'];
// Additional overhead for variable lookup
const prop = 'property';
const value = obj[prop];
|
The performance difference is negligible in most applications, so prioritize readability and maintainability over micro-optimizations.
Practical Examples and Best Practices
Working with APIs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// API response with mixed property naming conventions
const apiUser = {
id: 123,
'first-name': 'John',
'last-name': 'Doe',
email: 'john@example.com',
'created-at': '2023-01-15'
};
// Use appropriate notation for each property
const userProfile = {
id: apiUser.id, // dot notation
email: apiUser.email, // dot notation
firstName: apiUser['first-name'], // bracket notation
lastName: apiUser['last-name'], // bracket notation
createdAt: apiUser['created-at'] // bracket notation
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function processFormData(formData) {
const requiredFields = ['user-name', 'email-address', 'phone-number'];
const errors = [];
requiredFields.forEach(field => {
if (!formData[field] || formData[field].trim() === '') {
errors.push(`${field} is required`);
}
});
return {
isValid: errors.length === 0,
errors: errors
};
}
|
Configuration Objects
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const appConfig = {
apiUrl: 'https://api.example.com',
'api-version': 'v2',
'rate-limit': 1000,
'cache-duration': 300
};
// Mix notation types based on property names
function initializeApp() {
const baseUrl = appConfig.apiUrl; // dot notation
const version = appConfig['api-version']; // bracket notation
const rateLimit = appConfig['rate-limit']; // bracket notation
// Setup application with these values
}
|
Common Pitfalls to Avoid
1. Inconsistent Notation Usage
1
2
3
4
5
|
const user = { name: 'John', age: 30 };
// Inconsistent - stick to dot notation when possible
console.log(user.name);
console.log(user['age']); // Should be user.age
|
2. Forgetting Quotes in Bracket Notation
1
2
3
4
5
6
7
|
const obj = { property: 'value' };
// Wrong - this looks for a variable named 'property'
console.log(obj[property]); // ReferenceError
// Correct - property name as string
console.log(obj['property']);
|
3. Using Bracket Notation Unnecessarily
1
2
3
4
5
6
7
|
const user = { firstName: 'John', lastName: 'Doe' };
// Unnecessary bracket notation
const name = user['firstName'] + ' ' + user['lastName'];
// Better - use dot notation for known properties
const name = user.firstName + ' ' + user.lastName;
|
Dot or Bracket? The Cheat-Sheet to Picking the Right JavaScript Property Key
The choice between dot and bracket notation in JavaScript comes down to the specific requirements of your situation:
Use dot notation when:
- Property names are valid JavaScript identifiers
- You know the property names at write time
- You want cleaner, more readable code
- You need better IDE support and autocomplete
Use bracket notation when:
- Property names contain special characters or spaces
- Property names are dynamic or computed
- Property names start with numbers
- Property names come from external sources
- You’re building generic, reusable functions
Conclusion
Understanding these patterns will help you write more maintainable JavaScript code and avoid common pitfalls. Remember that consistency within your codebase is key to establish conventions with your team and stick to them throughout your project.
Both notations are powerful tools in the JavaScript developer’s toolkit. By choosing the right approach for each situation, you’ll create code that is not only functional but also clean, readable, and maintainable.
Author
If you liked the above story, you can
to keep me energized for writing stories like this for you.