Ini adalah model objek berbasis prototipe yang sangat sederhana yang akan dianggap sebagai sampel selama penjelasan, tanpa komentar:
function Person(name){
this.name = name;
}
Person.prototype.getName = function(){
console.log(this.name);
}
var person = new Person("George");
Ada beberapa poin penting yang harus kita pertimbangkan sebelum melalui konsep prototipe.
1- Cara kerja sebenarnya fungsi JavaScript:
Untuk mengambil langkah pertama kita harus mencari tahu, bagaimana fungsi JavaScript benar-benar bekerja, sebagai fungsi seperti kelas menggunakan this
kata kunci di dalamnya atau hanya sebagai fungsi biasa dengan argumennya, apa yang dilakukannya dan apa yang dikembalikan.
Katakanlah kita ingin membuat Person
model objek. tetapi dalam langkah ini saya akan mencoba melakukan hal yang persis sama tanpa menggunakan prototype
dan new
kata kunci .
Jadi pada langkah ini functions
, objects
dan this
kata kunci, adalah semua yang kita miliki.
Pertanyaan pertama adalah bagaimana this
kata kunci dapat berguna tanpa menggunakan new
kata kunci .
Jadi untuk menjawabnya katakanlah kita memiliki objek kosong, dan dua fungsi seperti:
var person = {};
function Person(name){ this.name = name; }
function getName(){
console.log(this.name);
}
dan sekarang tanpa menggunakan new
kata kunci bagaimana kita bisa menggunakan fungsi-fungsi ini. Jadi JavaScript memiliki 3 cara berbeda untuk melakukannya:
Sebuah. Cara pertama adalah memanggil fungsi sebagai fungsi biasa:
Person("George");
getName();//would print the "George" in the console
dalam hal ini, ini akan menjadi objek konteks saat ini, yang biasanya merupakan window
objek global di browser atau GLOBAL
di Node.js
. Itu berarti kita akan memiliki, window.name di browser atau GLOBAL.name di Node.js, dengan "George" sebagai nilainya.
b. Kita bisa melampirkannya ke objek, sebagai propertinya
- Cara termudah untuk melakukan ini adalah memodifikasi person
objek kosong , seperti:
person.Person = Person;
person.getName = getName;
dengan cara ini kita dapat memanggil mereka seperti:
person.Person("George");
person.getName();// -->"George"
dan sekarang person
objeknya seperti:
Object {Person: function, getName: function, name: "George"}
- Cara lain untuk melampirkan properti ke objek adalah menggunakan prototype
objek yang dapat ditemukan di objek JavaScript apa pun dengan nama __proto__
, dan saya telah mencoba menjelaskannya sedikit pada bagian ringkasan. Jadi kita bisa mendapatkan hasil yang serupa dengan melakukan:
person.__proto__.Person = Person;
person.__proto__.getName = getName;
Tapi dengan cara ini apa yang sebenarnya kita lakukan adalah memodifikasi Object.prototype
, karena setiap kali kita membuat objek JavaScript menggunakan literal ( { ... }
), itu akan dibuat berdasarkan Object.prototype
, yang berarti akan dilampirkan ke objek yang baru dibuat sebagai atribut yang dinamai __proto__
, jadi jika kita mengubahnya , seperti yang telah kami lakukan pada cuplikan kode kami sebelumnya, semua objek JavaScript akan berubah, bukan praktik yang baik. Jadi apa yang bisa menjadi praktik yang lebih baik sekarang:
person.__proto__ = {
Person: Person,
getName: getName
};
dan sekarang benda-benda lain dalam kedamaian, tetapi itu masih tampak bukan praktik yang baik. Jadi kita masih memiliki satu solusi lagi, tetapi untuk menggunakan solusi ini kita harus kembali ke baris kode tempat person
objek dibuat ( var person = {};
) lalu ubah seperti:
var propertiesObject = {
Person: Person,
getName: getName
};
var person = Object.create(propertiesObject);
apa yang dilakukannya adalah menciptakan JavaScript baru Object
dan melampirkan propertiesObject
ke __proto__
atribut. Jadi untuk memastikan Anda bisa melakukan:
console.log(person.__proto__===propertiesObject); //true
Tetapi poin yang sulit di sini adalah Anda memiliki akses ke semua properti yang ditentukan __proto__
pada tingkat pertama person
objek (baca bagian ringkasan untuk lebih detail).
seperti yang Anda lihat menggunakan salah satu dari dua cara this
ini persis akan menunjuk ke person
objek.
c. JavaScript memiliki cara lain untuk menyediakan fungsi this
, yaitu menggunakan panggilan atau menerapkan untuk memanggil fungsi.
Metode apply () memanggil fungsi dengan nilai ini dan argumen yang diberikan sebagai array (atau objek mirip array).
dan
Metode panggilan () memanggil fungsi dengan nilai ini dan argumen yang diberikan secara individual.
Dengan cara ini yang merupakan favorit saya, kami dapat dengan mudah memanggil fungsi kami seperti:
Person.call(person, "George");
atau
//apply is more useful when params count is not fixed
Person.apply(person, ["George"]);
getName.call(person);
getName.apply(person);
3 metode ini adalah langkah awal yang penting untuk mengetahui fungsionalitas .prototype.
2- Bagaimana cara kerja new
kata kunci?
ini adalah langkah kedua untuk memahami .prototype
fungsi ini. Inilah yang saya gunakan untuk mensimulasikan proses:
function Person(name){ this.name = name; }
my_person_prototype = { getName: function(){ console.log(this.name); } };
di bagian ini saya akan mencoba mengambil semua langkah yang diambil JavaScript, tanpa menggunakan new
kata kunci dan prototype
, ketika Anda menggunakan new
kata kunci. jadi ketika kita melakukannya new Person("George")
, Person
fungsi berfungsi sebagai konstruktor, Inilah yang dilakukan JavaScript, satu per satu:
Sebuah. pertama-tama ia membuat objek kosong, pada dasarnya hash kosong seperti:
var newObject = {};
b. langkah selanjutnya yang diambil JavaScript adalah melampirkan semua objek prototipe ke objek yang baru dibuat
kami miliki di my_person_prototype
sini mirip dengan objek prototipe.
for(var key in my_person_prototype){
newObject[key] = my_person_prototype[key];
}
Ini bukan cara JavaScript benar-benar melampirkan properti yang didefinisikan dalam prototipe. Cara aktual terkait dengan konsep rantai prototipe.
Sebuah. & b. Alih-alih dua langkah ini Anda dapat memiliki hasil yang sama persis dengan melakukan:
var newObject = Object.create(my_person_prototype);
//here you can check out the __proto__ attribute
console.log(newObject.__proto__ === my_person_prototype); //true
//and also check if you have access to your desired properties
console.log(typeof newObject.getName);//"function"
sekarang kita dapat memanggil getName
fungsi di my_person_prototype
:
newObject.getName();
c. maka itu memberikan objek itu ke konstruktor,
kita bisa melakukan ini dengan sampel kami seperti:
Person.call(newObject, "George");
atau
Person.apply(newObject, ["George"]);
maka constructor dapat melakukan apapun yang diinginkan, karena ini dalam konstruktor yang merupakan objek yang baru saja dibuat.
sekarang hasil akhirnya sebelum mensimulasikan langkah-langkah lain: Object {name: "George"}
Ringkasan:
Pada dasarnya, ketika Anda menggunakan kata kunci baru pada suatu fungsi, Anda memanggilnya dan fungsi itu berfungsi sebagai konstruktor, jadi ketika Anda mengatakan:
new FunctionName()
JavaScript internal membuat sebuah objek, sebuah hash kosong dan kemudian memberikan yang objek untuk konstruktor, maka konstruktor dapat melakukan apapun yang diinginkan, karena ini dalam konstruktor yang merupakan objek yang baru saja dibuat dan kemudian memberikan Anda bahwa objek tentu saja jika Anda belum menggunakan pernyataan pengembalian di fungsi Anda atau jika Anda telah meletakkan return undefined;
di akhir fungsi Anda.
Jadi ketika JavaScript pergi untuk mencari properti pada suatu objek, hal pertama yang dilakukannya, adalah mencarinya di objek itu. Dan kemudian ada properti rahasia [[prototype]]
yang biasanya kita suka __proto__
dan properti itu adalah apa yang terlihat JavaScript selanjutnya. Dan ketika ia melihat melalui __proto__
, sejauh itu lagi objek JavaScript lain, ia memiliki __proto__
atribut sendiri , itu naik dan naik sampai ke titik di mana berikutnya __proto__
adalah nol. Intinya adalah satu-satunya objek dalam JavaScript yang __proto__
atributnya null adalah Object.prototype
objek:
console.log(Object.prototype.__proto__===null);//true
dan itulah cara kerja warisan dalam JavaScript.
Dengan kata lain, ketika Anda memiliki properti prototipe pada suatu fungsi dan Anda memanggil yang baru pada itu, setelah JavaScript selesai melihat objek yang baru dibuat untuk properti, itu akan melihat fungsi .prototype
dan juga mungkin bahwa objek ini memiliki prototipe internal sendiri. dan seterusnya.