Advanced JavaScript (ES6+)

Enhanced Object Literals

13 min Lesson 7 of 40

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:

  1. Use property shorthand for name, price, and stock variables
  2. Add a computed property for category (using a variable)
  3. Include methods: getPrice() with tax calculation and isAvailable()

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 function keyword 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 this context
Next Up: In the next lesson, we'll explore Default Parameters and how they simplify function definitions!

ES
Edrees Salih
13 hours ago

We are still cooking the magic in the way!