We are still cooking the magic in the way!
Advanced JavaScript (ES6+)
Enhanced Object Literals
Enhanced Object Literals
ES6 introduced several enhancements to object literal syntax that make creating and working with objects more concise and powerful. These features reduce boilerplate code and make your JavaScript more readable and maintainable.
Property Shorthand
When a property name matches a variable name, you can use shorthand syntax to avoid repetition:
// ES5 - Verbose syntax
const name = 'Alice';
const age = 30;
const city = 'New York';
const person = {
name: name,
age: age,
city: city
};
// ES6+ - Property shorthand
const personES6 = {
name,
age,
city
};
console.log(personES6); // { name: 'Alice', age: 30, city: 'New York' }
Tip: Property shorthand is especially useful when creating objects from function parameters or destructured values, making your code much cleaner.
Method Shorthand
You can define methods more concisely without the function keyword:
// ES5 - Traditional method syntax
const calculator = {
add: function(a, b) {
return a + b;
},
subtract: function(a, b) {
return a - b;
}
};
// ES6+ - Method shorthand
const calculatorES6 = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
},
multiply(a, b) {
return a * b;
}
};
console.log(calculatorES6.add(5, 3)); // 8
console.log(calculatorES6.multiply(4, 2)); // 8
Computed Property Names
You can use expressions as property names by wrapping them in square brackets:
// Dynamic property names
const propName = 'score';
const student = {
name: 'Bob',
[propName]: 95,
['grade' + 'Level']: 'A'
};
console.log(student); // { name: 'Bob', score: 95, gradeLevel: 'A' }
// Using computed names with functions
const createUser = (field, value) => ({
id: Date.now(),
[field]: value
});
console.log(createUser('username', 'alice123'));
// { id: 1707123456789, username: 'alice123' }
console.log(createUser('email', 'alice@example.com'));
// { id: 1707123456790, email: 'alice@example.com' }
Note: Computed property names are evaluated at object creation time, allowing you to build dynamic object structures based on runtime values.
Combining Shorthand Syntax
You can mix and match all these features for clean, concise object creation:
const firstName = 'John';
const lastName = 'Doe';
const age = 28;
const user = {
// Property shorthand
firstName,
lastName,
age,
// Computed property
['full' + 'Name']() {
return `${this.firstName} ${this.lastName}`;
},
// Method shorthand
greet() {
return `Hello, I'm ${this.fullName()}`;
},
// Regular property
role: 'developer'
};
console.log(user.fullName()); // "John Doe"
console.log(user.greet()); // "Hello, I'm John Doe"
Practical Example: API Response Formatting
function formatUser(id, username, email, isActive) {
return {
// Property shorthand
id,
username,
email,
// Computed property
['is' + 'Active']: isActive,
// Method shorthand
getStatus() {
return this.isActive ? 'Active' : 'Inactive';
},
getProfile() {
return `${this.username} (${this.email})`;
},
// Mixed syntax
metadata: {
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
}
};
}
const user = formatUser(1, 'alice', 'alice@example.com', true);
console.log(user.getProfile()); // "alice (alice@example.com)"
console.log(user.getStatus()); // "Active"
Combining with Destructuring
Enhanced object literals work beautifully with destructuring:
// Extract and transform data
function processOrder({ id, product, quantity, price }) {
const total = quantity * price;
return {
// Property shorthand from parameters
id,
product,
quantity,
price,
// Computed value
total,
// Methods
getDiscount(percentage) {
return this.total * (percentage / 100);
},
getFinalPrice(discountPercentage = 0) {
return this.total - this.getDiscount(discountPercentage);
}
};
}
const order = processOrder({
id: 101,
product: 'Laptop',
quantity: 2,
price: 1000
});
console.log(order.total); // 2000
console.log(order.getFinalPrice(10)); // 1800 (10% discount)
Dynamic Object Creation Patterns
// Creating objects from arrays
const fields = ['name', 'email', 'age'];
const values = ['Alice', 'alice@example.com', 30];
const userFromArrays = fields.reduce((obj, field, index) => ({
...obj,
[field]: values[index]
}), {});
console.log(userFromArrays);
// { name: 'Alice', email: 'alice@example.com', age: 30 }
// Building configuration objects
const createConfig = (env) => ({
environment: env,
[`${env}Url`]: `https://${env}.example.com`,
[`is${env.charAt(0).toUpperCase() + env.slice(1)}`]: true
});
console.log(createConfig('production'));
// {
// environment: 'production',
// productionUrl: 'https://production.example.com',
// isProduction: true
// }
Object Property Enhancements in Practice
// State management pattern
const createStore = (initialState) => {
let state = initialState;
return {
// Getter
getState() {
return { ...state };
},
// Computed property with timestamp
['last' + 'Updated']: Date.now(),
// Update method
setState(updates) {
state = { ...state, ...updates };
this.lastUpdated = Date.now();
},
// Reset method
reset() {
state = initialState;
this.lastUpdated = Date.now();
}
};
};
const store = createStore({ count: 0, user: null });
store.setState({ count: 5 });
console.log(store.getState()); // { count: 5, user: null }
Best Practice: Use property and method shorthand whenever possible. It reduces code verbosity and makes objects easier to maintain. However, remember that arrow functions in method shorthand can cause issues with
this binding.
Common Pitfalls
// ❌ Arrow functions lose 'this' context in objects
const badExample = {
name: 'Alice',
greet: () => {
console.log(`Hello, ${this.name}`); // 'this' is undefined!
}
};
// ✅ Use method shorthand instead
const goodExample = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`); // Works correctly
}
};
// ❌ Computed property without brackets
const prop = 'score';
const wrong = {
prop: 100 // Creates property named 'prop', not 'score'
};
// ✅ Use brackets for computed properties
const correct = {
[prop]: 100 // Creates property named 'score'
};
Important: Method shorthand creates regular functions, not arrow functions. If you need
this to refer to the object, always use method shorthand, not arrow function properties.
Real-World Use Cases
// 1. Building API request objects
const createRequest = (endpoint, method = 'GET', data = null) => ({
url: `https://api.example.com/${endpoint}`,
method,
...(data && { body: JSON.stringify(data) }),
headers: {
'Content-Type': 'application/json'
},
send() {
return fetch(this.url, {
method: this.method,
body: this.body,
headers: this.headers
});
}
});
// 2. Form data transformation
const processFormData = (form) => {
const { username, email, password } = form;
return {
username,
email,
passwordHash: hashPassword(password),
isValid() {
return this.username && this.email && this.passwordHash;
}
};
};
// 3. Plugin configuration
const createPlugin = (name, options = {}) => ({
name,
enabled: true,
...options,
init() {
console.log(`Initializing plugin: ${this.name}`);
},
['destroy' + 'Plugin']() {
console.log(`Destroying plugin: ${this.name}`);
this.enabled = false;
}
});
Practice Exercise:
Task: Create a product object using enhanced object literals:
- Use property shorthand for
name,price, andstockvariables - Add a computed property for category (using a variable)
- Include methods:
getPrice()with tax calculation andisAvailable()
Solution:
const name = 'Laptop';
const price = 999;
const stock = 15;
const categoryType = 'category';
const taxRate = 0.1;
const product = {
// Property shorthand
name,
price,
stock,
// Computed property
[categoryType]: 'Electronics',
// Methods
getPrice(includeTax = true) {
return includeTax ? this.price * (1 + taxRate) : this.price;
},
isAvailable() {
return this.stock > 0;
},
getInfo() {
return `${this.name} - $${this.getPrice()} (${this.stock} in stock)`;
}
};
console.log(product.getInfo()); // "Laptop - $1098.9 (15 in stock)"
console.log(product.isAvailable()); // true
Summary
In this lesson, you learned:
- Property shorthand eliminates repetition when property names match variables
- Method shorthand removes the
functionkeyword for cleaner syntax - Computed property names use expressions in square brackets
[expr] - All features can be combined for powerful object creation patterns
- Enhanced literals work great with destructuring and spread operators
- Use method shorthand (not arrow functions) when you need
thiscontext
Next Up: In the next lesson, we'll explore Default Parameters and how they simplify function definitions!