Langsung ke konten
Belajar Javascript

Constructor dalam JavaScript: Panduan Lengkap dari Dasar hingga Mahir

Foto TaufiqOleh Taufiq
Constructor didalam Javascript

Constructor di dalam Javascript adalah fondasi dari setiap objek yang kamu bangun—momen ketika blueprint berubah menjadi sesuatu yang nyata. Pernahkah kamu membeli rak flat-pack di toko furniture? Di dalam kardusnya semua komponen sudah tersedia rapi: papan, sekrup, dan buku panduan. Namun rak itu belum bisa dipakai sampai kamu merakitnya sesuai urutan. Constructor bekerja persis seperti proses perakitan tersebut. Ia menerima bahan mentah berupa parameter, lalu menyusunnya menjadi objek utuh yang siap digunakan oleh programmu. Tanpa constructor, kamu akan terus-menerus merakit objek secara manual satu per satu, dan risiko lupa memasang satu sekrup saja sangat besar. Bayangkan betapa melelahkannya mengulang proses yang sama untuk 100 objek berbeda! Artikel ini mengajak kamu membedah constructor di dalam Javascript secara menyeluruh: mulai dari era pra-ES6, sintaks class modern, peran kata kunci this, pewarisan dengan super(), sampai kesalahan umum yang sering menjebak. Siapkan editor atau DevTools dan mari mulai merakit objek pertama kita bersama-sama.

Apa Itu Constructor dalam JavaScript?

Secara definisi, constructor adalah method khusus yang dieksekusi otomatis pada saat objek baru diciptakan. Tugasnya tunggal namun vital: menyiapkan kondisi awal objek—mengisi properti, menetapkan nilai default, hingga menjalankan logika tertentu sebelum objek benar-benar dipakai. Tanpa constructor, kamu terpaksa mengatur setiap properti secara manual satu per satu, dan itu resep pasti bagi inkonsistensi data. Bayangkan harus menulis obj.name = "Budi"; obj.age = 25; obj.createdAt = new Date() berulang kali untuk setiap pengguna baru; satu baris lupa, datanya sudah cacat.

Menariknya, JavaScript tidak selalu punya sintaks class. Sebelum standar ES6 dirilis tahun 2015, developer memanfaatkan function biasa sebagai constructor lalu memanggilnya lewat operator new:

JavaScript Snippet JavaScript
function Car(brand, color) {
 this.brand = brand;
 this.color = color;
}

Car.prototype.honk = function () {
 console.log(`${this.brand} berbunyi: Tin tin!`);
};

const myCar = new Car('Toyota', 'merah');
myCar.honk(); // Toyota berbunyi: Tin tin!

Pola ini tetap valid hingga kini dan masih banyak dijumpai di codebase warisan. Sejak ES6, JavaScript mengadopsi sintaks class yang jauh lebih rapi. Dokumentasi Classes di MDN Web Docs menjelaskan bahwa class modern sesungguhnya hanyalah syntactic sugar di atas mekanisme prototype yang sama—di balik layar, tidak ada yang berubah secara fundamental. Yang berubah hanyalah cara kita menulisnya.

Contoh Dasar Constructor dengan ES6 Class

Bandingkan dengan versi modern dari class Car yang sama:

JavaScript Snippet JavaScript
class Car {
 constructor(brand, color) {
 this.brand = brand;
 this.color = color;
 this.speed = 0; // nilai default
 }

 honk() {
 console.log(`${this.brand} berbunyi: Tin tin!`);
 }
}

const avanza = new Car('Toyota', 'putih');
console.log(avanza.brand); // Toyota
avanza.honk(); // Toyota berbunyi: Tin tin!

Mari bedah kode di atas:

  • class Car — mendefinisikan class bernama Car. Konvensi JavaScript: nama class diawali huruf kapital.
  • constructor(brand, color) — method khusus yang otomatis dipanggil saat menjalankan new Car(...). Parameter yang dikirim menjadi nilai awal properti.
  • this.brand = brand — this merujuk pada instance baru yang sedang dibuat. Jadi this.brand adalah properti milik objek tersebut.
  • this.speed = 0 — properti default yang tidak berasal dari parameter; semua mobil baru otomatis berkecepatan nol.
  • new Car('Toyota', 'putih') — keyword new yang memicu pemanggilan constructor dan mengembalikan objek baru.

Yang menarik, constructor tidak harus hanya menyalin parameter. Kamu bisa menanamkan logika tambahan sebelum properti diisi—misalnya validasi atau perhitungan nilai turunan—sehingga objek lahir dalam keadaan konsisten sejak detik pertama.

Constructor dengan Logika dan Validasi

Siapa bilang constructor hanya bisa this.x = x? Kita bisa menambahkan logika di dalamnya. Contoh berikut memastikan data pengguna selalu valid sejak awal:

JavaScript Snippet JavaScript
class User {
 constructor(name, email, age) {
 if (!name || name.trim().length < 3) throw new Error('Nama minimal 3 karakter');
 if (age < 0) throw new Error('Umur tidak valid');
 this.name = name.trim();
 this.email = email.toLowerCase();
 this.age = age;
 this.isMinor = age < 18;
 this.createdAt = new Date();
 }
}

try {
 const u1 = new User('Budi', 'BUDI@Mail.com', 25);
 console.log(u1.name); // Budi
 console.log(u1.email); // budi@mail.com
 console.log(u1.isMinor); // false
 console.log(u1.createdAt); // Date saat ini
 const u2 = new User('Al', 'al@mail.com', 15); // Error: nama terlalu pendek
} catch(e){
 console.log(e.message);
}

Perhatikan beberapa hal:

  • Constructor melakukan validasi sebelum properti diinisialisasi—mengecek panjang nama dan keabsahan umur.
  • Kita menghitung properti turunan isMinor berdasarkan age; tidak perlu di-input terpisah.
  • Metadata createdAt otomatis terisi waktu pembuatan objek, berguna untuk audit.
  • Kenapa validasi diletakkan di constructor dan bukan di luar? Karena constructor adalah gerbang tunggal pembuatan objek; jika gerbangnya dijaga, semua instance dijamin konsisten.

Memahami Peran this (dan Jebakan Arrow Function)

Kata kunci this adalah jantung dari setiap constructor. Di dalam constructor, this merujuk pada instance yang sedang dibuat, sehingga this.name = name berarti “pasang properti name pada objek baru ini”. Bayangkan this seperti kata ganti “saya”: saat Budi berkata “Saya suka bakso”, “saya” merujuk ke Budi. Sama halnya, saat constructor berjalan untuk new User('Budi'), this merujuk ke objek Budi yang baru lahir.

Namun this punya jebakan klasik terkait arrow function. Arrow function tidak memiliki this sendiri; ia meminjam this dari scope tempat ia didefinisikan. Perhatikan perbedaan ini:

JavaScript Snippet JavaScript
const person = {
 name: 'Budi',
 sayHelloRegular(){
 console.log(`Halo, saya ${this.name}`);
 },
 sayHelloArrow: () => {
 console.log(`Halo, saya ${this.name}`); // this pinjam dari global → undefined
 }
};
person.sayHelloRegular(); // Halo, saya Budi
person.sayHelloArrow(); // Halo, saya undefined

Di dalam class, jebakan ini muncul saat memakai callback. Pola aman: gunakan method biasa untuk perilaku objek, dan arrow function hanya untuk callback yang butuh this terikat. Atau definisikan arrow sebagai field di constructor:

JavaScript Snippet JavaScript
class Timer {
 constructor(name){
 this.name = name;
 this.seconds = 0;
 this.tick = () => {
 this.seconds++;
 console.log(`${this.name}: ${this.seconds}`);
 };
 }
}
const t = new Timer('Belajar');
// tick tetap ingat this meski dipanggil via setInterval
setInterval(t.tick, 1000);

Aturan emasnya: jangan gunakan arrow function untuk method di dalam objek literal jika butuh this yang merujuk ke objek itu sendiri. Untuk pemahaman lebih mendalam, baca MDN — this yang menjelaskan konteks eksekusi secara komprehensif.

Method Lain di Dalam Class

Constructor hanya membuka panggung; method-method berikutnya yang menjalankan pertunjukan. Setelah kondisi awal terpasang, method lain bertugas memanipulasi state tersebut:

JavaScript Snippet JavaScript
class BankAccount {
 constructor(owner, balance){
 this.owner = owner;
 this.balance = balance;
 }
 deposit(amount){
 if (amount <= 0) throw new Error('Nominal harus positif');
 this.balance += amount;
 return this;
 }
 withdraw(amount){
 if (amount > this.balance) throw new Error('Saldo kurang');
 this.balance -= amount;
 return this;
 }
 getInfo(){
 return `${this.owner}: Rp${this.balance}`;
 }
}

const acc = new BankAccount('Rina', 100000);
acc.deposit(50000).withdraw(30000);
console.log(acc.getInfo()); // Rina: Rp120000

Pola di atas menunjukkan pembagian peran yang sehat: constructor menetapkan keadaan awal, method lain mengubah atau membaca keadaan tersebut, dan return this memungkinkan chaining yang elegan.

Constructor Chaining dengan super() untuk Inheritance

Saat sebuah class mewarisi class lain, constructor keduanya terlibat dalam proses pembentukan objek. Di sinilah super() berperan—ia memanggil constructor induk sebelum class anak menambahkan propertinya sendiri.

JavaScript Snippet JavaScript
class Vehicle {
 constructor(brand, wheels){
 this.brand = brand;
 this.wheels = wheels;
 }
 start(){
 console.log(`${this.brand} mulai berjalan.`);
 }
}

class Car extends Vehicle {
 constructor(brand, wheels, fuelType){
 super(brand, wheels); // wajib dipanggil sebelum menyentuh this
 this.fuelType = fuelType;
 }
 start(){
 super.start(); // jalankan dulu versi induk
 console.log(`Bahan bakar: ${this.fuelType}`);
 }
}

const jazz = new Car('Honda', 4, 'bensin');
jazz.start();
// Honda mulai berjalan.
// Bahan bakar: bensin

Aturannya keras tapi jelas: dalam constructor class turunan, super() harus dipanggil sebelum baris mana pun yang menyentuh this. Langgar aturan itu dan JavaScript melempar ReferenceError: Must call super constructor before accessing 'this'. Alasannya masuk akal—objek induk belum selesai dibangun, jadi belum ada fondasi untuk ditempeli properti tambahan. Pola yang sama berlaku pada method: super.start() memanggil implementasi induk, lalu subclass memperluasnya tanpa menulis ulang dari nol.

Kesalahan Umum Saat Bekerja dengan Constructor

Pengalaman menunjukkan sebagian besar bug seputar constructor berasal dari segelintir pola yang berulang. Berikut yang paling sering muncul beserta cara menghindarinya.

Pertama, lupa operator new. Memanggil class seperti fungsi biasa membuat this tidak menunjuk ke instance baru:

JavaScript Snippet JavaScript
class Book {
 constructor(title){
 this.title = title;
 }
}
const book = Book('Belajar JS'); // TypeError di mode strict
console.log(typeof book); // undefined

Kedua, mengembalikan objek dari constructor. Jika constructor mengembalikan objek secara eksplisit, objek itu menggantikan instance yang baru dibuat—perilaku yang hampir selalu tidak disengaja:

JavaScript Snippet JavaScript
class Box {
 constructor(item){
 this.item = item;
 return { hacked: true }; // menggantikan instance!
 }
}
const box = new Box('laptop');
console.log(box.item); // undefined
console.log(box.hacked); // true

Ketiga, mengandalkan operasi asinkron di constructor. Constructor tidak bisa await; hasil fetch() adalah Promise, bukan datanya:

JavaScript Snippet JavaScript
class ApiClient {
 constructor(url){
 this.url = url;
 this.data = fetch(url); // ini Promise, bukan isi respons!
 }
}

Pola yang lebih sehat: pisahkan inisialisasi asinkron ke method tersendiri seperti async init() atau gunakan factory function—fungsi statis yang membuat, mengisi, lalu mengembalikan instance yang sudah siap pakai.

Keempat, menulis dua constructor dalam satu class (misalnya meniru overloading dari Java atau C++). JavaScript tidak mendukung overloading constructor; solusinya adalah parameter opsional atau objek konfigurasi sebagai argumen tunggal.

Studi Kasus: Constructor di Aplikasi Nyata

Teori terasa berbeda ketika dihadapkan pada kode produksi. Tiga skenario berikut menggambarkan bagaimana constructor dipakai di lapangan.

E-commerce: Objek Product

Pada aplikasi toko daring, setiap produk yang masuk keranjang idealnya berupa objek dengan harga dan stok yang sudah terjamin valid:

JavaScript Snippet JavaScript
class Product {
 constructor({ id, name, price, stock }){
 if (price <= 0) throw new Error('Harga harus lebih dari nol.');
 if (stock < 0) throw new Error('Stok tidak boleh negatif.');
 this.id = id;
 this.name = name;
 this.price = price;
 this.stock = stock;
 this.inStock = stock > 0;
 this.createdAt = new Date();
 }
 applyDiscount(percent){
 return this.price * (1 - percent/100);
 }
}

const p1 = new Product({ id: 1, name: 'Kaos', price: 150000, stock: 20 });
console.log(p1.inStock); // true
console.log(p1.applyDiscount(10)); // 135000

Game Development: Karakter

JavaScript Snippet JavaScript
class Character {
 constructor(name, hp, weapon){
 this.name = name;
 this.hp = hp;
 this.weapon = weapon;
 this.alive = true;
 }
 takeDamage(amount){
 this.hp -= amount;
 if (this.hp <= 0) this.alive = false;
 }
}

const hero = new Character('Arga', 100, 'pedang');
hero.takeDamage(30);
console.log(hero.hp); // 70

React Class Component

JavaScript Snippet JavaScript
class Welcome extends React.Component {
 constructor(props){
 super(props);
 this.state = { count: 0 };
 }
 increment = () => this.setState({ count: this.state.count + 1 });
}

Dari ketiga contoh terlihat pola yang sama: constructor menyiapkan state awal, validasi, dan nilai turunan, sementara method menangani perilaku. Di ekosistem React, constructor pada class component memang kini jarang ditulis karena hooks telah mengambil alih, namun memahaminya tetap penting saat kamu merawat kode legacy. Pola serupa juga muncul pada factory pattern di banyak framework backend maupun frontend. Kalau ingin memperdalam dasar-dasarnya, panduan JavaScript di Infanthree membahas topik pendukung seperti scope, closure, dan prototype secara bertahap.

Rangkuman

  • Constructor dipanggil otomatis via new dan bertugas menyiapkan kondisi awal objek.
  • Kata kunci this di dalam constructor selalu merujuk pada instance baru yang sedang dibuat.
  • Constructor bisa memuat validasi, perhitungan properti turunan, hingga penetapan nilai default.
  • Pada class turunan, super() wajib dipanggil sebelum menyentuh this.
  • Hindari lupa new, return objek asing, operasi async di constructor, dan harapan overload.

Pada akhirnya, constructor adalah cetakan yang menentukan kualitas setiap objek yang lahir darinya. Cetakan yang rapi menghasilkan aplikasi yang konsisten; cetakan yang ceroboh menanam bug sejak detik pertama. Sekarang giliranmu: buka editor, tulis satu class sederhana, lalu eksperimenlah dengan menambahkan validasi atau nilai default baru. Apa yang terjadi jika kamu sengaja memanggil super() setelah this? Menemukan jawabannya sendiri adalah cara tercepat untuk benar-benar menguasai constructor di dalam Javascript.

Hal yang sering ditanyakan seputar Constructor dalam JavaScript: Panduan Lengkap dari Dasar hingga Mahir

Apa itu constructor dalam JavaScript?

Constructor adalah method khusus yang dieksekusi otomatis saat objek baru diciptakan. Tugasnya menyiapkan kondisi awal objek seperti mengisi properti, menetapkan nilai default, dan menjalankan logika inisialisasi sebelum objek digunakan.

Mengapa constructor penting dalam pembuatan objek?

Tanpa constructor, developer harus mengatur setiap properti secara manual untuk setiap objek. Hal ini memakan waktu, rentan kesalahan, dan menyebabkan inkonsistensi data karena satu baris yang terlupa saja bisa membuat objek menjadi cacat.

Bagaimana cara kerja constructor dalam sintaks class ES6?

Dalam sintaks class ES6, constructor didefinisikan menggunakan kata kunci `constructor` di dalam blok class. Method ini otomatis dipanggil saat instance baru dibuat menggunakan kata kunci `new`, dan menerima parameter untuk menginisialisasi properti objek.

Apa perbedaan constructor pra-ES6 dengan sintaks class modern?

Sebelum ES6, constructor dibuat menggunakan function biasa yang dipanggil dengan `new`. Setelah ES6, JavaScript menyediakan sintaks `class` yang lebih rapi dan mudah dibaca, namun di bawah kap mesin tetap menggunakan mekanisme prototype yang sama.

Apa kesalahan umum yang sering terjadi saat menggunakan constructor?

Kesalahan umum meliputi lupa menggunakan kata kunci `new` saat memanggil constructor, tidak mengembalikan `this` secara eksplisit pada konstruksi pra-ES6, serta kesalahan dalam pewarisan properti menggunakan `super()` yang dipanggil sebelum `this` diinisialisasi.

Komentar

Memuat komentar…

Tinggalkan Komentar

Alamat email Anda tidak akan dipublikasikan.