LearnFrenzy
Sign in Take a free test

JavaScript interview · Set 4 of 10

Arrays, Objects and Modern ES6+ Features

  • 6 follow-up questions
  • 4 key points
  • Code examples
Test yourself

Transform data without surprises

Chain array methods clearly, never mutate shared state by accident, and choose the right container. These habits are what interviewers look for in front-end and Node developers.

  • Arraysmap, filter, reduce, sort and mutation.
  • ObjectsDestructuring, spread, copies and Map/Set.
  • ModulesES modules, dynamic import and tree-shaking.

Day-to-day JavaScript is mostly transforming arrays and objects — API responses, form data, state updates. Interviewers ask you to chain array methods, update objects without mutating them, and choose between objects, Maps and Sets.

1. Explain map, filter and reduce with a real example.

map transforms each element, filter keeps those that pass a test, reduce folds everything into one value. None of them change the original array.

const orders = [
  { id: 1, city: 'Pune', amount: 499, status: 'paid' },
  { id: 2, city: 'Delhi', amount: 250, status: 'failed' },
  { id: 3, city: 'Pune', amount: 120, status: 'paid' },
];

const revenueByCity = orders
  .filter(o => o.status === 'paid')
  .reduce((acc, o) => ({ ...acc, [o.city]: (acc[o.city] ?? 0) + o.amount }), {});
// { Pune: 619 }

2. Which array methods mutate, and which return a new array?

Mutating: push, pop, shift, unshift, splice, sort, reverse, fill. Non-mutating: map, filter, slice, concat, spread, and the newer toSorted, toReversed, toSpliced and with. In React or Redux state, always use non-mutating versions.

const prices = [300, 100, 200];
const sorted = prices.toSorted((a, b) => a - b);   // [100, 200, 300]
console.log(prices);                               // [300, 100, 200] unchanged
const updated = prices.with(1, 150);               // [300, 150, 200]

3. Why does [10, 9, 1].sort() give [1, 10, 9]?

Without a compare function, sort converts elements to strings and sorts them by UTF-16 code units, so “10” comes before “9”. Always pass a comparator for numbers, and localeCompare for human-friendly string sorting.

[10, 9, 1].sort();                 // [1, 10, 9]
[10, 9, 1].sort((a, b) => a - b);  // [1, 9, 10]
names.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));

4. Show destructuring, default values and rest/spread.

Destructuring pulls values out of arrays and objects into variables, with defaults and renaming. Rest collects the remaining items; spread expands an iterable or copies object properties.

const { name, address: { city = 'Unknown' } = {}, ...rest } = user;
const [first, , third = 0] = [10, 20];

function total(...nums) { return nums.reduce((a, b) => a + b, 0); }
total(...[1, 2, 3]);                     // 6
const merged = { ...defaults, ...overrides };

5. Shallow copy vs deep copy — how do you do each?

Spread and Object.assign make shallow copies: nested objects are still shared. structuredClone() makes a deep copy of plain data, dates, maps and sets (not functions or class prototypes). JSON.parse(JSON.stringify(x)) loses dates, undefined and Infinity — avoid it.

const original = { user: { name: 'Asha' }, tags: ['a'] };
const shallow = { ...original };
shallow.user.name = 'Ravi';
console.log(original.user.name);   // 'Ravi' — shared!

const deep = structuredClone(original);
deep.user.name = 'Meera';
console.log(original.user.name);   // 'Ravi' — unaffected

6. Map and Set vs plain objects and arrays — when to use which?

Use a Map when keys are not strings (objects, numbers), when you add and remove keys often, or when you need the size and insertion order reliably. Use an object for fixed-shape records and JSON. Use a Set for unique values and fast membership checks.

const visits = new Map();
visits.set(userObj, 3);                     // object as key
console.log(visits.get(userObj), visits.size);

const unique = [...new Set([3, 1, 3, 2, 1])];   // [3, 1, 2]
const allowed = new Set(['admin', 'editor']);
allowed.has(role);                             // O(1)

7. How do you update nested objects immutably?

Copy each level you change with spread, leaving untouched branches shared. For deep or frequent updates, libraries such as Immer let you write “mutating” code that produces a new object.

const state = { user: { name: 'Asha', prefs: { theme: 'light' } }, cart: [] };

const next = {
  ...state,
  user: { ...state.user, prefs: { ...state.user.prefs, theme: 'dark' } },
};
console.log(state.user.prefs.theme, next.user.prefs.theme);   // light dark

8. What are ES modules and how do they differ from CommonJS?

ES modules use import/export, are statically analysable (so bundlers can tree-shake unused code), load asynchronously and run in strict mode — the standard in browsers and modern Node. CommonJS (require/module.exports) is Node's older, synchronous system.

// math.js
export const add = (a, b) => a + b;
export default function multiply(a, b) { return a * b; }

// app.js
import multiply, { add } from './math.js';
const { heavyChart } = await import('./chart.js');   // dynamic import, loaded on demand

Remember

Key points

  • sort() mutates and stringifies

    Pass a comparator or use toSorted.

  • Spread is shallow

    structuredClone for deep copies.

  • Map for dynamic keys

    Set for uniqueness and fast lookups.

  • Copy every changed level

    Immutable nested updates.

Interview drill

Follow-up questions

What the interviewer asks after your first answer. Turn on practice mode, answer each one aloud, then reveal.

  1. 1 What is the difference between find, filter and some? Basic

    find returns the first match (or undefined), filter returns all matches in a new array, some returns a boolean as soon as one matches.

  2. 2 forEach vs map? Basic

    forEach runs side effects and returns undefined; map returns a new array of results. You cannot break out of either — use a for...of loop for that.

  3. 3 How do you remove duplicates of objects by id? Intermediate

    Keep a Map keyed by id.

    const uniqueById = [...new Map(items.map(i => [i.id, i])).values()];
  4. 4 What does Object.freeze do? Intermediate

    It prevents adding, removing or changing properties of an object — but only shallowly; nested objects stay mutable.

  5. 5 How do you group items by a key? Intermediate

    Use Object.groupBy(items, item => item.city) (modern runtimes) or reduce.

  6. 6 What is the difference between for...in and for...of? Basic

    for...in loops over enumerable property keys (including inherited ones); for...of loops over values of an iterable such as an array, string, Map or Set.

Preparing with friends?

Share this page with your study group or placement batch.

Popular