Practice Questions

1. With an example, explain the difference between dot notation and bracket notation for accessing object properties. When would you prefer one over the other?

Solution

Both dot and bracket notation access object properties, but you use them in different situations:

const user = { name: "Alice", "job title": "Developer" };

// Dot notation - cleaner, but only works with valid identifiers
console.log(user.name); // "Alice"

// Bracket notation - required for keys with spaces or special characters
console.log(user["job title"]); // "Developer"

// Bracket notation is also needed for dynamic keys
const key = "name";
console.log(user[key]); // "Alice"

Use dot notation when the property name is a valid identifier and you know it at write-time. Use bracket notation when the property name contains spaces or special characters, or when the key is stored in a variable (dynamic access).

2. What is destructuring? Provide an example showing how to extract specific values from both an object and an array.

Solution

Destructuring is syntax that pulls values out of an array, or properties out of an object, and puts them into separate variables.

// Object destructuring
const person = { name: "Bob", age: 25, city: "NYC" };
const { name, age } = person;
console.log(name, age); // "Bob" 25

// Array destructuring
const colors = ["red", "green", "blue"];
const [first, second] = colors;
console.log(first, second); // "red" "green"

// You can also use the rest syntax to capture remaining values
const { city, ...rest } = person;
console.log(city, rest); // "NYC" { name: "Bob", age: 25 }

3. A student wants to store user IDs (which are numbers) as keys in a collection with associated user data. They suggest using a plain object. Is this a good idea? What would you recommend instead, and why?

Solution

Using a plain object for numeric keys works, but a Map would be a better choice. Here is why:

// With plain object - keys are converted to strings
const usersObj = {};
usersObj[123] = { name: "Alice" };
console.log(Object.keys(usersObj)); // ["123"] - key became a string!

// With Map - keys retain their original type
const usersMap = new Map();
usersMap.set(123, { name: "Alice" });
console.log(usersMap.get(123)); // { name: "Alice" }
console.log(usersMap.has(123)); // true
console.log(usersMap.has("123")); // false - strict key comparison

Use a Map when:

  • Keys are not strings (numbers, objects, etc.)
  • You need to frequently add/remove entries
  • You need to know the collection size easily (map.size)
  • You want guaranteed iteration order

4. If you want to generate a random integer between 5 and 15 (inclusive), how would you do it? Explain your approach.

Solution

To generate a random integer in a range, combine Math.random() with Math.floor():

// Math.random() returns 0 to < 1
// To get 5 to 15 inclusive, we need 11 possible values (5,6,7...15)

const min = 5;
const max = 15;
const randomInt = Math.floor(Math.random() * (max - min + 1)) + min;
console.log(randomInt); // Random integer from 5 to 15

The formula works like this:

  1. Math.random() gives a number from 0 (inclusive) to 1 (exclusive)
  2. Multiply by (max - min + 1) to scale the range (here, 11)
  3. Math.floor() converts to an integer (0 to 10)
  4. Add min to shift the range (5 to 15)

5. Provide any two interesting facts about how JavaScript’s Date object handles invalid or out-of-range values when constructing dates.

Solution

Two interesting facts about Date handling:

  1. Out-of-range values are automatically converted to a valid date instead of throwing errors:
// Month 13 rolls over to February of next year
const date1 = new Date(2024, 13, 1);
console.log(date1); // February 1, 2025

// Negative days roll backward
const date2 = new Date(2024, 2, -1);
console.log(date2); // February 28, 2024
  1. Invalid date inputs produce an “Invalid Date” (its time value is NaN), so you can detect it safely:
const bad = new Date("not a real date");
console.log(bad); // Invalid Date
console.log(Number.isNaN(bad.getTime())); // true

Two other facts worth knowing: months are zero-indexed (January = 0), and date string formats that are not standardized may be parsed differently across browsers.

6. You have an array that may contain duplicate values, and you need to get only the unique values. How would you accomplish this using Set?

Solution

Use Set to automatically filter duplicates, then convert back to an array:

const numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];

// Create a Set from the array (duplicates are removed)
const uniqueSet = new Set(numbers);

// Convert back to an array
const unique = Array.from(uniqueSet);
// Or using spread: const unique = [...uniqueSet];

console.log(unique); // [1, 2, 3, 4]

This is more efficient than filtering with indexOf or includes because Set’s has() operation is , while array lookups are .

7. Write code that starts with an empty array, adds the values 10, 20, and 30 to it (one at a time), then removes the last value. What methods would you use, and what is the final array?

Solution

Use push() to add values and pop() to remove the last one:

const numbers = [];
numbers.push(10); // [10]
numbers.push(20); // [10, 20]
numbers.push(30); // [10, 20, 30]
numbers.pop();    // Removes 30

console.log(numbers); // [10, 20]
  • push(value) adds an element to the end of the array
  • pop() removes and returns the last element

Both methods modify the original array. The final array is [10, 20].

8. Given the following 2D array representing a tic-tac-toe board, write code to access the center cell and the bottom-right cell:

const board = [
  ["X", "O", "X"],
  ["O", "X", "O"],
  ["O", "X", "O"],
];
Solution

Use two bracket pairs to access elements in a 2D array. The first index selects the row, and the second selects the column:

const board = [
  ["X", "O", "X"],
  ["O", "X", "O"],
  ["O", "X", "O"],
];

// Center cell: row 1, column 1
const center = board[1][1];
console.log(center); // "X"

// Bottom-right cell: row 2, column 2
const bottomRight = board[2][2];
console.log(bottomRight); // "O"

Remember that array indices are zero-based, so the first row/column is index 0.

9. Explain the difference between Math.floor() and Math.trunc(). When do they produce different results?

Solution

Both remove the fractional part of a number, but they behave differently with negative numbers:

// With positive numbers - same result
console.log(Math.floor(5.7)); // 5
console.log(Math.trunc(5.7)); // 5

// With negative numbers - different results!
console.log(Math.floor(-5.7)); // -6
console.log(Math.trunc(-5.7)); // -5
  • Math.floor() rounds toward negative infinity (always down on the number line)
  • Math.trunc() rounds toward zero (just removes decimals)

For negative numbers, floor(-5.7) returns -6 because -6 is less than -5.7 on the number line. trunc(-5.7) returns -5 because it simply removes the .7 portion.

Use trunc when you want to discard decimals regardless of sign. Use floor when you need mathematical floor behavior (e.g., for array indices or coordinate systems).

10. When would you choose to use a Set instead of an Array? Provide any two scenarios with brief explanations.

Solution

Scenario 1: Tracking visited items or membership

When you need to quickly check if something has been seen or processed:

// Tracking visited URLs in a web crawler
const visitedUrls = new Set();

function processUrl(url) {
  if (visitedUrls.has(url)) return; // O(1) lookup
  visitedUrls.add(url);
  // ... fetch and process
}

With an array, includes() would be O(n) for each check.

Scenario 2: Ensuring unique tags or categories

When duplicates should be automatically prevented:

// User can add tags, but we don't want duplicates
const tags = new Set();
tags.add("javascript");
tags.add("programming");
tags.add("javascript"); // Silently ignored

console.log(tags.size); // 2

With an array, you would need to manually check before each insertion.

Use arrays when you need index-based access, allow duplicates, or require array methods like map, filter, and reduce.

11. Rewrite the following code using object destructuring with renaming:

const response = { status: 200, data: { name: "Alice", role: "admin" } };
const statusCode = response.status;
const userName = response.data.name;
Solution

Using destructuring with renaming:

const response = { status: 200, data: { name: "Alice", role: "admin" } };

// Destructure and rename in one statement
const {
  status: statusCode,
  data: { name: userName },
} = response;

console.log(statusCode); // 200
console.log(userName); // "Alice"

The syntax { original: newName } extracts the property original and assigns it to a variable called newName. You can also use nested destructuring to extract values from nested objects in a single statement.

12. Given the variables below, create an object using shorthand property syntax and computed property syntax:

const name = "Alice";
const score = 95;
const key = "grade";
const value = "A";

The resulting object should be: { name: "Alice", score: 95, grade: "A" }

Solution
const name = "Alice";
const score = 95;
const key = "grade";
const value = "A";

// Using shorthand syntax for name and score,
// and computed property syntax for the dynamic key
const result = {
  name,           // shorthand for name: name
  score,          // shorthand for score: score
  [key]: value,   // computed property: grade: "A"
};

console.log(result); // { name: "Alice", score: 95, grade: "A" }

Shorthand property syntax allows you to write { name } instead of { name: name } when the variable name matches the key. Computed properties (using [expression]) let you use a variable’s value as the key name.

13. What is JSON and how does it relate to JavaScript objects? Describe the key differences between JSON format and JavaScript object literal syntax.

Solution

JSON (JavaScript Object Notation) is a text format for data. Its syntax comes from JavaScript object syntax, and it is commonly used to exchange data between systems.

Key differences from JavaScript object literals:

// JavaScript object literal - flexible
const jsObject = {
  name: "Alice", // Unquoted key (valid identifier)
  age: 30, // Unquoted key (valid identifier)
  isActive: true,
  greet: function () {}, // Functions allowed
};

// JSON - stricter rules
const jsonString = `{
  "name": "Alice",
  "age": 30,
  "isActive": true
}`;

Differences:

  1. JSON keys must be double-quoted strings
  2. JSON values can only be: strings, numbers, booleans, null, arrays, or objects (no functions, undefined, or special values)
  3. JSON does not allow trailing commas
  4. JSON does not allow comments

Converting between them:

const obj = { name: "Alice", age: 30 };
const json = JSON.stringify(obj); // '{"name":"Alice","age":30}'
const parsed = JSON.parse(json); // { name: "Alice", age: 30 }