Wednesday

18-06-2025 Vol 19

Difference between __proto__, [[Prototype]] & .prototype in JavaScript

Memahami Perbedaan: __proto__, [[Prototype]], dan .prototype di JavaScript

JavaScript, sebagai bahasa berbasis prototipe, menggunakan konsep prototipe secara ekstensif. Namun, pemahaman tentang bagaimana prototipe bekerja, dan khususnya perbedaan antara __proto__, [[Prototype]], dan .prototype, sering kali membingungkan bagi pengembang JavaScript, baik pemula maupun berpengalaman. Artikel ini bertujuan untuk menjernihkan kebingungan tersebut, memberikan penjelasan mendalam dan contoh praktis untuk menguasai konsep-konsep penting ini.

Mengapa Memahami Prototipe Penting?

Sebelum kita menyelami detail spesifik, mari kita pahami mengapa pemahaman prototipe sangat penting dalam JavaScript:

  1. Warisan: JavaScript menggunakan warisan prototipe, bukan warisan berbasis kelas seperti dalam bahasa lain seperti Java atau C++. Memahami prototipe memungkinkan Anda untuk memanfaatkan kekuatan warisan ini untuk menulis kode yang efisien dan dapat digunakan kembali.
  2. Pemahaman Tingkat Lanjut: Banyak fitur JavaScript tingkat lanjut, seperti closure dan fungsi pembangun, sangat bergantung pada pemahaman tentang prototipe.
  3. Debug Lebih Efektif: Ketika Anda menghadapi masalah dengan warisan atau perilaku objek yang tidak terduga, pemahaman yang kuat tentang prototipe akan membantu Anda mendiagnosis dan memperbaiki masalah dengan lebih efektif.
  4. Wawancara Kerja: Konsep prototipe sering kali menjadi topik utama dalam wawancara kerja JavaScript. Menunjukkan pemahaman yang mendalam tentang topik ini akan meningkatkan peluang Anda.

Kerangka Artikel:

  1. Pendahuluan:
    • Mengapa memahami prototipe penting?
    • Tujuan artikel: Menjelaskan perbedaan antara __proto__, [[Prototype]], dan .prototype.
  2. Dasar-Dasar Prototipe:
    • Apa itu prototipe?
    • Warisan Prototipe: Cara objek mewarisi properti dari prototipenya.
    • Rantai Prototipe: Bagaimana prototipe saling terkait.
  3. Mendalami __proto__:
    • Apa itu __proto__?
    • Bagaimana cara menggunakan __proto__ untuk mengakses prototipe objek.
    • Mengapa __proto__ tidak boleh digunakan dalam kode produksi.
    • Contoh penggunaan dan peringatan.
  4. Mengenal [[Prototype]]:
    • Apa itu [[Prototype]]?
    • Bagaimana [[Prototype]] berhubungan dengan __proto__.
    • Cara mengakses [[Prototype]] menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf().
    • Manfaat menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf().
  5. Memahami .prototype:
    • Apa itu .prototype?
    • Bagaimana .prototype digunakan dengan fungsi pembangun (constructor functions).
    • Cara menambahkan properti dan metode ke prototipe fungsi pembangun.
    • Contoh penggunaan untuk membuat kelas dan mewarisi properti.
  6. Perbedaan Utama:
    • Ringkasan perbedaan antara __proto__, [[Prototype]], dan .prototype dalam bentuk tabel.
    • Kapan menggunakan masing-masing.
  7. Contoh Lengkap:
    • Contoh kode yang menunjukkan penggunaan __proto__, [[Prototype]], dan .prototype dalam skenario yang berbeda.
  8. Praktik Terbaik:
    • Cara menghindari kesalahan umum terkait prototipe.
    • Tips untuk menulis kode JavaScript yang lebih bersih dan efisien menggunakan prototipe.
  9. Kesimpulan:
    • Ringkasan poin-poin penting.
    • Sumber daya tambahan untuk dipelajari lebih lanjut tentang prototipe.

Dasar-Dasar Prototipe

Apa itu prototipe? Dalam JavaScript, setiap objek memiliki prototipe. Prototipe itu sendiri adalah objek. Ketika Anda mencoba mengakses properti objek, dan objek tersebut tidak memiliki properti tersebut secara langsung, JavaScript akan mencari properti tersebut di prototipenya. Ini terus berlanjut hingga mencapai prototipe teratas, yaitu null.

Warisan Prototipe: Warisan prototipe adalah mekanisme di mana objek mewarisi properti dan metode dari prototipenya. Ini memungkinkan Anda untuk membuat objek baru berdasarkan objek yang sudah ada, memperluas fungsionalitasnya tanpa harus menulis ulang kode yang sama.

Rantai Prototipe: Rantai prototipe adalah serangkaian objek yang saling terhubung melalui prototipe mereka. Setiap objek dalam rantai memiliki prototipe, dan prototipe tersebut mungkin memiliki prototipe lain, dan seterusnya. Ujung rantai prototipe adalah null, yang merupakan prototipe dari Object.prototype.

Mendalami __proto__

Apa itu __proto__? __proto__ (dua garis bawah di depan dan belakang) adalah properti yang digunakan untuk mengakses prototipe suatu objek. Secara teknis, itu adalah getter dan setter untuk properti internal [[Prototype]] dari suatu objek. Ini adalah cara yang lebih tua dan kurang direkomendasikan untuk berinteraksi dengan prototipe suatu objek.

Bagaimana cara menggunakan __proto__? Anda dapat menggunakan __proto__ untuk membaca atau mengubah prototipe suatu objek. Contoh:

“`javascript
const animal = {
name: “Animal”,
makeSound: function() {
console.log(“Generic animal sound”);
}
};

const dog = {
name: “Dog”,
bark: function() {
console.log(“Woof!”);
}
};

// Menetapkan prototipe dog ke animal
dog.__proto__ = animal;

console.log(dog.name); // Output: Dog (properti sendiri)
console.log(dog.makeSound()); // Output: Generic animal sound (diwarisi dari prototipe)
dog.bark(); // Output: Woof! (properti sendiri)
“`

Mengapa __proto__ tidak boleh digunakan dalam kode produksi? Meskipun mudah digunakan, __proto__ memiliki beberapa masalah:

  1. Kinerja: Mengubah prototipe objek setelah dibuat dapat memengaruhi kinerja, terutama jika Anda melakukannya berulang kali.
  2. Standardisasi: __proto__ bukan bagian dari standar ECMAScript sampai edisi terbaru. Meskipun didukung secara luas di browser modern, menggunakan metode standar lebih disarankan untuk kompatibilitas yang lebih baik.
  3. Mutasi Prototipe: Mengubah prototipe secara langsung dapat menyebabkan efek samping yang tidak terduga, terutama jika Anda tidak berhati-hati.

Contoh penggunaan dan peringatan:

“`javascript
const person = {
name: “John”,
greet: function() {
console.log(“Hello, my name is ” + this.name);
}
};

const employee = {
employeeId: 123
};

// Hati-hati! Ini bisa berdampak pada kinerja dan kompatibilitas
employee.__proto__ = person;

employee.greet(); // Output: Hello, my name is John
console.log(employee.employeeId); // Output: 123
“`

Peringatan: Hindari penggunaan __proto__ dalam kode produksi. Gunakan Object.getPrototypeOf() dan Object.setPrototypeOf() sebagai gantinya, yang dibahas di bagian selanjutnya.

Mengenal [[Prototype]]

Apa itu [[Prototype]]? [[Prototype]] adalah properti internal yang dimiliki setiap objek dalam JavaScript. Properti ini menunjuk ke prototipe objek tersebut. Anda tidak dapat mengakses [[Prototype]] secara langsung menggunakan notasi titik atau kurung. Ini adalah properti internal.

Bagaimana [[Prototype]] berhubungan dengan __proto__? __proto__ adalah getter dan setter yang digunakan untuk mendapatkan dan menetapkan nilai dari properti internal [[Prototype]]. Dengan kata lain, __proto__ adalah cara yang disediakan oleh beberapa lingkungan JavaScript untuk berinteraksi dengan [[Prototype]], meskipun tidak direkomendasikan untuk kode produksi.

Cara mengakses [[Prototype]] menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf():

Untuk mengakses dan memodifikasi [[Prototype]], gunakan metode standar yang disediakan oleh JavaScript:

  • Object.getPrototypeOf(obj): Mengembalikan prototipe (yaitu, nilai dari [[Prototype]]) dari objek yang ditentukan.
  • Object.setPrototypeOf(obj, prototype): Menetapkan prototipe (yaitu, nilai dari [[Prototype]]) dari objek yang ditentukan ke objek lain.

Contoh:

“`javascript
const animal = {
name: “Animal”,
makeSound: function() {
console.log(“Generic animal sound”);
}
};

const dog = {
name: “Dog”,
bark: function() {
console.log(“Woof!”);
}
};

// Menetapkan prototipe dog ke animal menggunakan Object.setPrototypeOf()
Object.setPrototypeOf(dog, animal);

console.log(dog.name); // Output: Dog
console.log(dog.makeSound()); // Output: Generic animal sound
dog.bark(); // Output: Woof!

// Mendapatkan prototipe dog menggunakan Object.getPrototypeOf()
const prototype = Object.getPrototypeOf(dog);
console.log(prototype === animal); // Output: true
“`

Manfaat menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf():

  1. Standar: Metode ini adalah bagian dari standar ECMAScript dan didukung di semua browser modern.
  2. Kinerja: Meskipun mengubah prototipe dapat memengaruhi kinerja, Object.setPrototypeOf() memberikan kontrol yang lebih baik dan dapat dioptimalkan oleh mesin JavaScript.
  3. Keamanan: Metode ini membantu mencegah mutasi prototipe yang tidak terduga.

Memahami .prototype

Apa itu .prototype? .prototype adalah properti yang dimiliki oleh fungsi (termasuk fungsi pembangun). Ini bukan properti yang dimiliki oleh objek biasa. Properti .prototype adalah objek yang menjadi prototipe untuk objek baru yang dibuat menggunakan fungsi tersebut sebagai konstruktor (dengan kata kunci new).

Bagaimana .prototype digunakan dengan fungsi pembangun? Ketika Anda membuat objek menggunakan kata kunci new dan fungsi pembangun, objek baru tersebut akan mewarisi properti dan metode dari properti .prototype fungsi pembangun tersebut.

Contoh:

“`javascript
function Person(name) {
this.name = name;
}

// Menambahkan metode ke Person.prototype
Person.prototype.greet = function() {
console.log(“Hello, my name is ” + this.name);
};

const john = new Person(“John”);
john.greet(); // Output: Hello, my name is John

const jane = new Person(“Jane”);
jane.greet(); // Output: Hello, my name is Jane
“`

Dalam contoh di atas, Person.prototype adalah objek yang menjadi prototipe untuk objek john dan jane. Kedua objek mewarisi metode greet dari Person.prototype.

Cara menambahkan properti dan metode ke prototipe fungsi pembangun: Anda dapat menambahkan properti dan metode ke prototipe fungsi pembangun dengan menetapkannya ke .prototype objek fungsi tersebut.

Contoh:

“`javascript
function Animal(name) {
this.name = name;
}

// Menambahkan properti ke Animal.prototype
Animal.prototype.species = “Unknown”;

// Menambahkan metode ke Animal.prototype
Animal.prototype.makeSound = function() {
console.log(“Generic animal sound”);
};

const cat = new Animal(“Cat”);
console.log(cat.name); // Output: Cat
console.log(cat.species); // Output: Unknown
cat.makeSound(); // Output: Generic animal sound
“`

Contoh penggunaan untuk membuat kelas dan mewarisi properti: .prototype adalah dasar dari warisan prototipe dalam JavaScript. Ini memungkinkan Anda untuk membuat “kelas” (meskipun JavaScript tidak memiliki kelas dalam arti tradisional) dan mewarisi properti dan metode dari kelas induk.

Contoh:

“`javascript
function Animal(name) {
this.name = name;
}

Animal.prototype.makeSound = function() {
console.log(“Generic animal sound”);
};

function Dog(name, breed) {
// Memanggil konstruktor Animal untuk mengatur properti name
Animal.call(this, name);
this.breed = breed;
}

// Menetapkan Dog.prototype untuk mewarisi dari Animal.prototype
Dog.prototype = Object.create(Animal.prototype);

// Mengatur properti constructor Dog.prototype kembali ke Dog
Dog.prototype.constructor = Dog;

// Menambahkan metode khusus untuk Dog
Dog.prototype.bark = function() {
console.log(“Woof!”);
};

// Meng-override metode makeSound dari Animal
Dog.prototype.makeSound = function() {
console.log(“Woof woof!”);
};

const myDog = new Dog(“Buddy”, “Golden Retriever”);
console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof woof!
myDog.bark(); // Output: Woof!
“`

Dalam contoh ini, Dog “mewarisi” dari Animal dengan menetapkan Dog.prototype ke objek baru yang dibuat dari Animal.prototype. Ini memungkinkan Dog untuk mewarisi properti dan metode dari Animal dan juga menambahkan properti dan metode khusus untuk Dog.

Perbedaan Utama

Mari kita ringkas perbedaan utama antara __proto__, [[Prototype]], dan .prototype dalam bentuk tabel:

Properti Deskripsi Penggunaan
__proto__ Getter/setter (kurang direkomendasikan) untuk properti internal [[Prototype]]. Mengakses atau mengubah prototipe suatu objek. Hindari dalam kode produksi.
[[Prototype]] Properti internal dari setiap objek yang menunjuk ke prototipenya. Tidak dapat diakses langsung. Diakses melalui Object.getPrototypeOf() dan Object.setPrototypeOf().
.prototype Properti dari fungsi pembangun yang menjadi prototipe untuk objek baru yang dibuat dengan new. Menambahkan properti dan metode ke prototipe objek yang dibuat dengan fungsi pembangun.

Kapan menggunakan masing-masing:

  • Object.getPrototypeOf(obj) dan Object.setPrototypeOf(obj, prototype): Gunakan ini untuk mendapatkan dan menetapkan prototipe objek dengan cara yang standar dan aman.
  • .prototype: Gunakan ini untuk menambahkan properti dan metode ke prototipe fungsi pembangun, yang akan diwarisi oleh objek baru yang dibuat dengan fungsi tersebut.
  • __proto__: Jangan gunakan dalam kode produksi. Hanya untuk keperluan debugging atau eksperimen.

Contoh Lengkap

Berikut adalah contoh lengkap yang menunjukkan penggunaan Object.getPrototypeOf(), Object.setPrototypeOf(), dan .prototype:

“`javascript
// Fungsi pembangun untuk Animal
function Animal(name) {
this.name = name;
}

// Menambahkan metode ke Animal.prototype
Animal.prototype.makeSound = function() {
console.log(“Generic animal sound”);
};

// Fungsi pembangun untuk Dog
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}

// Menetapkan Dog.prototype untuk mewarisi dari Animal.prototype
Object.setPrototypeOf(Dog.prototype, Animal.prototype);

// Mengatur properti constructor Dog.prototype kembali ke Dog
Dog.prototype.constructor = Dog;

// Menambahkan metode khusus untuk Dog
Dog.prototype.bark = function() {
console.log(“Woof!”);
};

// Meng-override metode makeSound dari Animal
Dog.prototype.makeSound = function() {
console.log(“Woof woof!”);
};

const myDog = new Dog(“Buddy”, “Golden Retriever”);

console.log(myDog.name); // Output: Buddy
console.log(myDog.breed); // Output: Golden Retriever
myDog.makeSound(); // Output: Woof woof!
myDog.bark(); // Output: Woof!

// Mendapatkan prototipe myDog
const animalPrototype = Object.getPrototypeOf(myDog);
console.log(animalPrototype === Animal.prototype); // Output: false
console.log(Object.getPrototypeOf(animalPrototype) === Animal.prototype); // Output: true

“`

Praktik Terbaik

Berikut adalah beberapa praktik terbaik untuk bekerja dengan prototipe di JavaScript:

  • Gunakan Object.getPrototypeOf() dan Object.setPrototypeOf(): Hindari penggunaan __proto__ dalam kode produksi.
  • Pahami rantai prototipe: Ketahui bagaimana objek mewarisi properti dari prototipe mereka.
  • Berhati-hatilah dengan mutasi prototipe: Mengubah prototipe secara langsung dapat menyebabkan efek samping yang tidak terduga.
  • Gunakan warisan prototipe untuk membuat kode yang dapat digunakan kembali: Warisan prototipe adalah cara yang kuat untuk mengatur kode Anda dan mengurangi duplikasi.
  • Pertimbangkan penggunaan sintaks kelas (ES6): Meskipun di belakang layar masih menggunakan warisan prototipe, sintaks kelas dapat membuat kode Anda lebih mudah dibaca dan dipahami.

Kesimpulan

Memahami perbedaan antara __proto__, [[Prototype]], dan .prototype adalah kunci untuk menguasai warisan prototipe di JavaScript. Ingatlah untuk menggunakan Object.getPrototypeOf() dan Object.setPrototypeOf() sebagai cara standar dan aman untuk berinteraksi dengan prototipe, dan gunakan .prototype untuk menambahkan properti dan metode ke prototipe fungsi pembangun.

Dengan pemahaman yang kuat tentang konsep-konsep ini, Anda akan dapat menulis kode JavaScript yang lebih efisien, dapat digunakan kembali, dan mudah dipahami.

Sumber Daya Tambahan:

“`

omcoding

Leave a Reply

Your email address will not be published. Required fields are marked *