Skillversitas

Destructuring in JavaScript

Destructuring is an ES6 syntax for "unpacking" values from an array or properties from an object into separate variables concisely. Destructuring saves many lines of code, especially when working with data from API responses, function parameters, or nested data.


Array Destructuring

// Without destructuring
const data = [85, 92, 78];
const midTermGrade = data[0];
const finalGrade = data[1];
const assignmentGrade = data[2];

// With destructuring — much more concise
const [midTermGrade, finalGrade, assignmentGrade] = [85, 92, 78];
console.log(midTermGrade); // 85

// Skip elements
const [first, , third] = [10, 20, 30, 40];
console.log(first); // 10
console.log(third);  // 30 (the second element is skipped)

// Rest pattern — collect the remaining elements
const [head, ...rest] = [1, 2, 3, 4, 5];
console.log(head);     // 1
console.log(rest);  // [2, 3, 4, 5]

// Default values
const [a = 10, b = 20, c = 30] = [5];
console.log(a); // 5 (has a value)
console.log(b); // 20 (default)
console.log(c); // 30 (default)

// Swap variables without a temporary variable
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1

Code Example: Object Destructuring

// Without destructuring
const student = {
  name: "John Smith",
  studentId: "2023001",
  majorCode: "Computer Science",
  gpa: 3.75
};

const name = student.name;
const studentId = student.studentId;

// With destructuring
const { name, studentId, majorCode, gpa } = student;
console.log(name); // "John Smith"

// Rename (alias)
const { name: fullName, gpa: studentGpa } = student;
console.log(fullName); // "John Smith"
console.log(studentGpa); // 3.75

// Default values
const { name, studentId, semester = 1, credits = 0 } = student;
console.log(semester); // 1 (default — not in the object)
console.log(credits);      // 0 (default)

// Rest pattern — collect the properties NOT destructured
const { name, ...remainingData } = student;
console.log(remainingData);
// { studentId: "2023001", majorCode: "Computer Science", gpa: 3.75 }

Nested Destructuring

// Nested object
const university = {
  name: "Nusantara University",
  faculty: {
    name: "Engineering Faculty",
    majorCode: {
      name: "Computer Science",
      accreditation: "A",
      departmentHead: "Dr. Aaron"
    }
  }
};

// Deep nested destructuring
const {
  faculty: {
    majorCode: { name: majorName, accreditation }
  }
} = university;

console.log(majorName); // "Computer Science"
console.log(accreditation); // "A"

// Nested array
const matriks = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

const [[a, b, c], [d, e, f]] = matriks;
console.log(a, b, c); // 1 2 3
console.log(d, e, f); // 4 5 6

Function Parameter Destructuring

// Without destructuring — parameters must be accessed via the object
function showStudent(student) {
  console.log(`${student.name} (${student.studentId}) — GPA: ${student.gpa}`);
}

// Destructuring in the parameter — much cleaner
function showStudent({ name, studentId, gpa }) {
  console.log(`${name} (${studentId}) — GPA: ${gpa}`);
}

showStudent({
  name: "John",
  studentId: "2023001",
  gpa: 3.75,
  extra: "not taken" // ignored
});

// With default values + rename
function createOrder({
  item: nameItem,
  count = 1,
  price,
  catatan = "No notes"
}) {
  return {
    nameItem,
    count,
    price,
    total: count * price,
    catatan
  };
}

const order = createOrder({
  item: "Lunch",
  price: 25000,
  count: 3
});
console.log(order);
// { nameItem: "Lunch", count: 3, price: 25000, total: 75000, catatan: "No notes" }

Code Explanation

Syntax Explanation
const [a, b] = [1, 2] Array destructuring
const { x, y } = obj Object destructuring
const { x: alias } = obj Rename property
const { x = 10 } = obj Default value
const [a, , b] = arr Skip array elements
const [first, ...rest] = arr Rest pattern
function({ x }) {} Parameter destructuring

Real-World Examples

1. Extracting Data from a Student API Response

// Simulated API response
const apiResponse = {
  status: 200,
  message: "Success",
  data: {
    student: {
      id: 1234,
      name: "John Smith",
      studentId: "2023001",
      majorCode: {
        code: "CS",
        name: "Computer Science",
        faculty: "FT"
      },
      grade: {
        midterm: 85,
        final: 90,
        assignment: [88, 92, 85]
      },
      active: true
    },
    timestamp: "2025-01-15T10:30:00Z"
  }
};

// ✅ Multi-level destructuring — extract only what's needed
const {
  data: {
    student: {
      name,
      studentId,
      majorCode: { name: majorName },
      grade: { midterm, final, assignment }
    }
  }
} = apiResponse;

// Calculate the assignment average
const averageAssignment = assignment.reduce((a, b) => a + b, 0) / assignment.length;

// Calculate the final grade
const finalGrade = (midterm * 0.3) + (final * 0.4) + (averageAssignment * 0.3);

console.log(`Student: ${name} (${studentId})`);
console.log(`Major: ${majorName}`);
console.log(`Midterm: ${midterm}, Final: ${final}`);
console.log(`Average Assignment: ${averageAssignment.toFixed(1)}`);
console.log(`Final grade: ${finalGrade.toFixed(1)}`);

2. Config Object for an Application

// Function with a config — destructuring + defaults
function initializeApplication({
  name = "Application Academic",
  versi = "1.0.0",
  environment = "development",
  database = { host: "localhost", port: 27017, name: "campus_dev" },
  debug = environment === "development"
} = {}) {
  console.log(`🚀 ${name} v${versi}`);
  console.log(`Environment: ${environment}`);
  console.log(`Database: ${database.host}:${database.port}/${database.name}`);
  console.log(`Debug mode: ${debug ? "ON" : "OFF"}`);

  return { name, versi, environment, database, debug };
}

// Default config
initializeApplication();

// Custom config — only override what's needed
initializeApplication({
  environment: "production",
  database: { host: "db.university.edu", port: 27017, name: "campus_prod" }
});

3. State Management Pattern

function useCounter(initialState = { count: 0, history: [] }) {
  // Destructure the state
  let { count, history } = initialState;

  return {
    increment() {
      count++;
      history = [...history, { action: "increment", value: count }];
      return { count, history };
    },
    decrement() {
      count--;
      history = [...history, { action: "decrement", value: count }];
      return { count, history };
    },
    reset() {
      const oldCount = count;
      count = 0;
      history = [...history, { action: "reset", from: oldCount }];
      return { count, history };
    },
    get() {
      return { count, history };
    }
  };
}

const counter = useCounter();
counter.increment();
counter.increment();
counter.increment();
counter.decrement();

const state = counter.get();
const { count, history } = state;
console.log(`Count: ${count}`); // 2
console.log(`History: ${history.length} actions`);

Conclusion

  • Array destructuring: const [a, b, c] = [1, 2, 3] — unpack an array into variables.
  • Object destructuring: const { x, y } = obj — unpack an object into variables.
  • Rename: const { x: newName } = obj — rename a variable while destructuring.
  • Default values: const { x = 10 } = obj — fallback if the property doesn't exist.
  • Nested: const { a: { b } } = obj — destructure multi-level properties.
  • Rest pattern: const { a, ...rest } = obj — collect the remaining properties.
  • Parameter destructuring: function({ x, y }) {} — concise for config/option objects.
  • Extremely useful for extracting data from API responses without accessing properties one by one.