javascript
exercises
exercises.js⚡javascript
/**
* ============================================
* 7.1 OBJECT BASICS - EXERCISES
* ============================================
*
* Practice creating, accessing, and manipulating objects.
*/
/**
* EXERCISE 1: Create an Object
* ----------------------------
* Create an object representing a book.
*/
console.log('=== Exercise 1: Create an Object ===');
// Create a book object with:
// - title: "JavaScript: The Good Parts"
// - author: "Douglas Crockford"
// - year: 2008
// - pages: 176
// - isAvailable: true
const book = {
// YOUR CODE HERE
};
console.log('Book:', book);
/*
* SOLUTION:
*/
const bookSolution = {
title: 'JavaScript: The Good Parts',
author: 'Douglas Crockford',
year: 2008,
pages: 176,
isAvailable: true,
};
console.log('Book Solution:', bookSolution);
/**
* EXERCISE 2: Access Properties
* -----------------------------
* Access various properties using both notations.
*/
console.log('\n=== Exercise 2: Access Properties ===');
const product = {
'product-name': 'Laptop',
brand: 'TechBrand',
'price-usd': 999,
specs: {
cpu: 'Intel i7',
ram: '16GB',
},
};
// Access "product-name" (use bracket notation)
const productName = null; // YOUR CODE
// Access "brand" (use dot notation)
const brandName = null; // YOUR CODE
// Access "price-usd" using a variable
const priceField = 'price-usd';
const price = null; // YOUR CODE
// Access nested "cpu" property
const cpu = null; // YOUR CODE
console.log('Product:', productName);
console.log('Brand:', brandName);
console.log('Price:', price);
console.log('CPU:', cpu);
/*
* SOLUTION:
* const productName = product["product-name"];
* const brandName = product.brand;
* const price = product[priceField];
* const cpu = product.specs.cpu;
*/
/**
* EXERCISE 3: Dynamic Properties
* ------------------------------
* Create an object with computed property names.
*/
console.log('\n=== Exercise 3: Dynamic Properties ===');
const prefix = 'user';
const id = 42;
// Create an object with these computed properties:
// - userName: "Alice"
// - userId: 42
// - user42_status: "active"
const userData = {
// YOUR CODE HERE
};
console.log('User data:', userData);
/*
* SOLUTION:
*/
const userDataSolution = {
[`${prefix}Name`]: 'Alice',
[`${prefix}Id`]: id,
[`${prefix}${id}_status`]: 'active',
};
console.log('User data solution:', userDataSolution);
/**
* EXERCISE 4: Property Shorthand
* ------------------------------
* Use ES6 shorthand syntax.
*/
console.log('\n=== Exercise 4: Property Shorthand ===');
const firstName = 'John';
const lastName = 'Doe';
const email = 'john@example.com';
const age = 25;
// Create an object using shorthand property syntax
const profile = null; // YOUR CODE: { firstName, lastName, ... }
console.log('Profile:', profile);
/*
* SOLUTION:
* const profile = { firstName, lastName, email, age };
*/
/**
* EXERCISE 5: Add and Modify Properties
* -------------------------------------
* Dynamically add and modify object properties.
*/
console.log('\n=== Exercise 5: Add and Modify ===');
const car = {
brand: 'Honda',
model: 'Civic',
};
// 1. Add a "year" property with value 2023
// 2. Add a "color" property with value "blue"
// 3. Change "model" to "Accord"
// 4. Add a nested "engine" object with { type: "V6", hp: 280 }
// YOUR CODE HERE
console.log('Modified car:', car);
/*
* SOLUTION:
* car.year = 2023;
* car["color"] = "blue";
* car.model = "Accord";
* car.engine = { type: "V6", hp: 280 };
*/
/**
* EXERCISE 6: Check for Properties
* --------------------------------
* Use different methods to check if properties exist.
*/
console.log('\n=== Exercise 6: Check Properties ===');
const config = {
timeout: 0,
retries: undefined,
debug: false,
};
// Check if each property exists using 'in' operator
const hasTimeout = null; // YOUR CODE
const hasRetries = null; // YOUR CODE
const hasMaxSize = null; // YOUR CODE
// Check if 'timeout' is an OWN property (not inherited)
const ownsTimeout = null; // YOUR CODE
console.log('Has timeout:', hasTimeout); // true
console.log('Has retries:', hasRetries); // true
console.log('Has maxSize:', hasMaxSize); // false
console.log('Owns timeout:', ownsTimeout); // true
/*
* SOLUTION:
* const hasTimeout = "timeout" in config;
* const hasRetries = "retries" in config;
* const hasMaxSize = "maxSize" in config;
* const ownsTimeout = config.hasOwnProperty("timeout");
*/
/**
* EXERCISE 7: Delete Properties
* -----------------------------
* Remove unwanted properties.
*/
console.log('\n=== Exercise 7: Delete Properties ===');
const userProfile = {
id: 1,
name: 'Alice',
password: 'secret123',
email: 'alice@example.com',
_internal: 'debug data',
};
// Delete the 'password' and '_internal' properties
// YOUR CODE HERE
console.log('Cleaned profile:', userProfile);
console.log('Password exists:', 'password' in userProfile); // false
/*
* SOLUTION:
* delete userProfile.password;
* delete userProfile._internal;
*/
/**
* EXERCISE 8: Optional Chaining
* -----------------------------
* Safely access nested properties.
*/
console.log('\n=== Exercise 8: Optional Chaining ===');
const response = {
data: {
users: [
{ name: 'Alice', profile: { avatar: 'alice.jpg' } },
{ name: 'Bob' },
],
},
};
// Safely access Alice's avatar
const aliceAvatar = null; // YOUR CODE (should be "alice.jpg")
// Safely access Bob's avatar (doesn't exist)
const bobAvatar = null; // YOUR CODE (should be undefined)
// Safely access a non-existent path
const missingData = null; // YOUR CODE: response.missing?.deep?.value
console.log('Alice avatar:', aliceAvatar);
console.log('Bob avatar:', bobAvatar);
console.log('Missing data:', missingData);
/*
* SOLUTION:
* const aliceAvatar = response.data?.users?.[0]?.profile?.avatar;
* const bobAvatar = response.data?.users?.[1]?.profile?.avatar;
* const missingData = response.missing?.deep?.value;
*/
/**
* EXERCISE 9: Nullish Coalescing
* ------------------------------
* Provide default values correctly.
*/
console.log('\n=== Exercise 9: Nullish Coalescing ===');
const settings = {
volume: 0, // Valid: 0 means muted
brightness: null, // Needs default
theme: '', // Valid: empty means default theme
language: undefined, // Needs default
};
// Use ?? to get values with proper defaults
const volume = null; // YOUR CODE: settings.volume ?? 50
const brightness = null; // YOUR CODE: settings.brightness ?? 100
const theme = null; // YOUR CODE: settings.theme ?? "dark"
const language = null; // YOUR CODE: settings.language ?? "en"
console.log('Volume:', volume); // 0 (not 50!)
console.log('Brightness:', brightness); // 100
console.log('Theme:', theme); // "" (not "dark"!)
console.log('Language:', language); // "en"
/*
* SOLUTION:
* const volume = settings.volume ?? 50;
* const brightness = settings.brightness ?? 100;
* const theme = settings.theme ?? "dark";
* const language = settings.language ?? "en";
*/
/**
* EXERCISE 10: Build an Object Factory
* ------------------------------------
* Create a function that builds user objects.
*/
console.log('\n=== Exercise 10: Object Factory ===');
function createUser(name, email, options = {}) {
// Create and return a user object with:
// - id: random number
// - name: from parameter
// - email: from parameter
// - role: from options or default "user"
// - createdAt: current date
// YOUR CODE HERE
return {};
}
const newUser = createUser('Alice', 'alice@example.com', { role: 'admin' });
console.log('New user:', newUser);
/*
* SOLUTION:
*/
function createUserSolution(name, email, options = {}) {
return {
id: Math.floor(Math.random() * 10000),
name,
email,
role: options.role ?? 'user',
createdAt: new Date(),
};
}
console.log('Solution user:', createUserSolution('Bob', 'bob@example.com'));
/**
* EXERCISE 11: Merge Objects
* --------------------------
* Combine multiple objects.
*/
console.log('\n=== Exercise 11: Merge Objects ===');
const defaults = {
theme: 'light',
fontSize: 14,
showSidebar: true,
};
const userPrefs = {
theme: 'dark',
fontSize: 16,
};
// Merge defaults and userPrefs (userPrefs should override)
const finalSettings = null; // YOUR CODE: use spread operator
console.log('Final settings:', finalSettings);
/*
* SOLUTION:
* const finalSettings = { ...defaults, ...userPrefs };
*/
/**
* EXERCISE 12: Object Destructuring with Defaults
* ------------------------------------------------
* Extract values with default fallbacks.
*/
console.log('\n=== Exercise 12: Destructuring ===');
const apiResponse = {
status: 200,
data: { items: [1, 2, 3] },
// error is missing
};
// Destructure with defaults:
// - status (no default needed)
// - data (no default needed)
// - error (default to null)
// - message (default to "Success")
// YOUR CODE: const { status, ... } = apiResponse;
// console.log("Status:", status);
// console.log("Data:", data);
// console.log("Error:", error); // null
// console.log("Message:", message); // "Success"
/*
* SOLUTION:
*/
const { status, data, error = null, message = 'Success' } = apiResponse;
console.log('Status:', status);
console.log('Data:', data);
console.log('Error:', error);
console.log('Message:', message);
/**
* EXERCISE 13: Count Properties
* -----------------------------
* Write a function to count object properties.
*/
console.log('\n=== Exercise 13: Count Properties ===');
function countProperties(obj) {
// Return the number of own properties
// YOUR CODE HERE
return 0;
}
const testObj = { a: 1, b: 2, c: 3, d: 4 };
console.log('Property count:', countProperties(testObj)); // 4
/*
* SOLUTION:
*/
function countPropertiesSolution(obj) {
return Object.keys(obj).length;
}
console.log('Solution count:', countPropertiesSolution(testObj));
/**
* EXERCISE 14: Filter Object Properties
* -------------------------------------
* Create a new object with only specified keys.
*/
console.log('\n=== Exercise 14: Filter Properties ===');
function pick(obj, keys) {
// Return new object with only the specified keys
// YOUR CODE HERE
return {};
}
const fullUser = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
password: 'secret',
createdAt: '2023-01-01',
};
const publicUser = pick(fullUser, ['id', 'name', 'email']);
console.log('Public user:', publicUser);
/*
* SOLUTION:
*/
function pickSolution(obj, keys) {
const result = {};
for (const key of keys) {
if (key in obj) {
result[key] = obj[key];
}
}
return result;
}
console.log('Solution pick:', pickSolution(fullUser, ['id', 'name', 'email']));
/**
* EXERCISE 15: Transform Object
* -----------------------------
* Transform an object using a mapping function.
*/
console.log('\n=== Exercise 15: Transform Object ===');
function mapObject(obj, fn) {
// Apply fn to each value, return new object
// fn receives (value, key)
// YOUR CODE HERE
return {};
}
const prices = {
apple: 1.5,
banana: 0.75,
orange: 2.0,
};
const doublePrices = mapObject(prices, (value) => value * 2);
console.log('Double prices:', doublePrices);
const labeledPrices = mapObject(prices, (value, key) => `${key}: $${value}`);
console.log('Labeled prices:', labeledPrices);
/*
* SOLUTION:
*/
function mapObjectSolution(obj, fn) {
const result = {};
for (const [key, value] of Object.entries(obj)) {
result[key] = fn(value, key);
}
return result;
}
console.log(
'Solution doubled:',
mapObjectSolution(prices, (v) => v * 2)
);
console.log('\n=== Exercises Complete ===');