Setiap objek dalam JavaScript memiliki prototipe properti bawaan. Penjelasan properti prototipe suatu objek dalam JavaScript adalah: mengembalikan referensi ke prototipe tipe objek. Ini berarti bahwa atribut prototipe memegang referensi ke objek JavaScript lain, yang bertindak sebagai induk dari objek saat ini.
Salinan kode adalah sebagai berikut:
A.prototype = b () baru;
Memahami prototipe tidak boleh dikacaukan dengan warisan. Prototipe A adalah contoh dari B. Dapat dipahami bahwa A mengkloning semua metode dan sifat dalam B. A dapat menggunakan metode dan sifat B. Apa yang ditekankan di sini adalah kloning daripada warisan. Ini bisa terjadi: prototipe A adalah instance dari B, dan prototipe B juga merupakan instance dari A.
Terus lihat analisis berikut:
Variabel dan fungsi pribadi
Jika variabel dan fungsi yang ditentukan di dalam fungsi tidak disediakan secara eksternal, mereka tidak dapat diakses secara eksternal, yaitu variabel pribadi dan fungsi fungsi.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {
var color = "blue"; // variabel pribadi
var fn = fungsi () // fungsi pribadi
{
}
}
</script>
Dengan cara ini, warna variabel dan FN tidak dapat diakses di luar kotak objek fungsi, dan mereka menjadi pribadi:
Salinan kode adalah sebagai berikut:
var obj = box baru ();
waspada (obj.color); // pop-up yang tidak ditentukan
waspada (obj.fn); // sama seperti di atas
Variabel dan fungsi statis
Ketika suatu fungsi didefinisikan, atribut dan fungsi yang ditambahkan kepadanya masih dapat diakses melalui objek itu sendiri, tetapi contohnya tidak dapat diakses. Variabel dan fungsi tersebut masing -masing disebut variabel statis dan fungsi statis.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
fungsi obj () {};
Obj.num = 72; // variabel statis
Obj.fn = fungsi () // fungsi statis
{
}
waspada (obj.num); // 72
Peringatan (Tipeof Obj.fn) // Fungsi
var t = new obj ();
alert (t.name); // tidak ditentukan
waspada (typeof t.fn); // tidak terdefinisi
</script>
Variabel dan fungsi instance
Dalam pemrograman yang berorientasi pada objek, di samping beberapa fungsi perpustakaan, kami masih berharap untuk mendefinisikan beberapa properti dan metode pada saat yang sama ketika definisi objek, sehingga mereka dapat diakses setelah instantiasi, dan JS juga dapat melakukan ini.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {
this.a = []; // variabel instance
this.fn = function () {// Metode instance
}
}
console.log (typeof box.a); //belum diartikan
console.log (typeof box.fn); //belum diartikan
var box = box baru ();
console.log (typeof box.a); //obyek
console.log (typeof box.fn); //fungsi
</script>
Tambahkan metode dan properti baru ke variabel dan metode instance
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {
this.a = []; // variabel instance
this.fn = function () {// Metode instance
}
}
var box1 = box baru ();
box1.a.push (1);
box1.fn = {};
console.log (box1.a); // [1]
console.log (typeof box1.fn); //obyek
var box2 = box baru ();
console.log (box2.a); // []
console.log (typeof box2.fn); //fungsi
</script>
A dan FN dimodifikasi dalam Box1, tetapi tidak di Box2. Karena array dan fungsi adalah objek dan merupakan tipe referensi, ini berarti bahwa meskipun properti dan metode di Box1 sama dengan yang ada di Box2, mereka bukan referensi, tetapi salinan properti dan metode yang ditentukan oleh objek kotak.
Ini tidak memiliki masalah dengan properti, tetapi ini adalah masalah besar untuk metode, karena metode melakukan fungsi yang persis sama, tetapi ada dua salinan. Jika objek fungsi memiliki ribuan dan metode instance, maka setiap contohnya harus mempertahankan salinan ribuan metode. Ini jelas tidak ilmiah. Apa yang bisa saya lakukan? Prototipe muncul.
Konsep Dasar
Setiap fungsi yang kami buat memiliki properti prototipe, yang merupakan pointer ke suatu objek, dan tujuannya adalah untuk berisi properti dan metode yang dapat dibagikan oleh semua contoh jenis tertentu. Kemudian, prototipe adalah objek prototipe dari instance objek yang dibuat dengan memanggil konstruktor.
Keuntungan menggunakan prototipe adalah memungkinkan instance objek untuk berbagi properti dan metode yang dikandungnya. Artinya, alih -alih menambahkan informasi objek definisi ke konstruktor, Anda dapat secara langsung menambahkan informasi ini ke prototipe. Masalah utama dengan menggunakan konstruktor adalah bahwa setiap metode perlu dibuat sekali dalam setiap instance.
Dalam JavaScript, ada dua jenis nilai, nilai asli dan nilai objek. Setiap objek memiliki prototipe properti internal, yang biasanya kami sebut prototipe. Nilai prototipe dapat berupa objek atau nol. Jika nilainya adalah objek, objek tersebut juga harus memiliki prototipe sendiri. Ini membentuk rantai linier, yang kami sebut rantai prototipe.
arti
Fungsi dapat digunakan sebagai konstruktor. Selain itu, hanya fungsi yang memiliki atribut prototipe dan dapat diakses, tetapi instance objek tidak memiliki atribut ini, hanya ada atribut __proto__ yang tidak dapat diakses internal. __Proto__ adalah tautan misterius dalam objek ke prototipe yang relevan. Menurut standar, __proto__ tidak diungkapkan kepada publik, yang berarti itu adalah properti pribadi, tetapi mesin Firefox mengeksposnya dan menjadi properti umum, yang dapat kami akses dan atur.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
var browser = function () {};
Browser.prototype.run = function () {
waspada ("Saya tokek, kernel Firefox");
}
var bro = browser baru ();
Bro.run ();
</script>
Ketika kita memanggil metode bro.run (), karena tidak ada metode seperti itu di Bro, dia akan mencarinya di __proto__ -nya, yaitu, browser.prototype, sehingga metode run () akhirnya dieksekusi. (Di sini, surat fungsi yang dikapitalisasi mewakili konstruktor untuk membedakan fungsi biasa)
Saat memanggil konstruktor untuk membuat instance, instance akan berisi pointer internal (__proto__) yang menunjuk ke prototipe konstruktor. Koneksi ini ada antara instance dan prototipe konstruktor, bukan antara instance dan konstruktor.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
Function Person (Name) {// Fungsi Konstruktor
this.name = name;
}
Orang.prototype.printname = function () // objek prototipe
{
waspada (this.name);
}
var person1 = orang baru ('byron'); // instantiate objek
console.log (person1 .__ proto __); // orang
console.log (person1.constructor); // Cobalah sendiri untuk melihat apa yang akan terjadi
console.log (person.prototype); // Tunjuk ke orang objek prototipe
var person2 = orang baru ('Frank');
</script>
Instance Person1 orang berisi atribut nama, dan secara otomatis menghasilkan atribut __proto__, yang menunjuk ke prototipe orang, dan Anda dapat mengakses metode printname yang ditentukan dalam prototipe, yang mungkin seperti ini:
Setiap fungsi JavaScript memiliki atribut prototipe, yang mengacu pada objek, yang merupakan objek prototipe. Objek prototipe kosong saat diinisialisasi. Kami dapat menyesuaikan properti dan metode apa pun di dalamnya. Metode dan sifat ini akan diwarisi oleh objek yang dibuat oleh konstruktor.
Jadi, sekarang masalahnya adalah. Apa hubungan antara konstruktor, instance dan objek prototipe?
Perbedaan antara konstruktor, instance dan objek prototipe
Contoh dibuat melalui konstruktor. Setelah instance dibuat, ia memiliki atribut konstruktor (menunjuk ke fungsi konstruktor) dan atribut __proto__ (menunjuk ke objek prototipe).
Ada properti prototipe dalam konstruktor, yang merupakan pointer untuk objek prototipe.
Ada juga pointer (properti konstruktor) di dalam objek prototipe yang menunjuk ke konstruktor: orang.prototype.constructor = orang;
Contoh dapat mengakses properti dan metode yang ditentukan pada objek prototipe.
Di sini orang1 dan orang2 adalah contoh, dan prototipe adalah objek prototipe mereka.
Chestnut lain:
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
Function Animal (Name) // Mengumpulkan Konstruktor
{
this.name = name; // atur properti objek
}
Animal.prototype.behavior = function () // Tambahkan metode perilaku ke prototipe konstruktor kelas dasar
{
alert ("Ini adalah"+this.name);
}
var dog = hewan baru ("anjing"); // buat objek anjing
var kucing = hewan baru ("kucing"); // buat objek kucing
Dog.behavior (); // panggil metode perilaku langsung melalui objek anjing
Cat.behavior (); // output "Ini adalah kucing"
waspada (dog.behavior == cat.behavior); // output true;
</script>
Dapat dilihat dari program yang menjalankan hasil bahwa metode yang ditentukan pada prototipe konstruktor memang dapat dipanggil langsung melalui objek, dan kode dibagikan. (Anda dapat mencoba menghapus properti prototipe di animal.prototype.behavior untuk melihat apakah masih dapat berjalan.) Di sini, properti prototipe menunjuk ke objek hewan.
Instance objek array
Mari kita lihat contoh objek array. Ketika kami membuat objek array1, model objek aktual array1 di mesin JavaScript adalah sebagai berikut:
Salinan kode adalah sebagai berikut:
var array1 = [1,2,3];
Objek Array1 memiliki nilai atribut panjang 3, tetapi kami dapat menambahkan elemen ke array1 dengan metode berikut:
Salinan kode adalah sebagai berikut:
array1.push (4);
Metode Push berasal dari metode yang menunjuk ke objek oleh anggota __proTo__ dari array1 (array.prototye.push ()). Justru karena semua objek array (dibuat melalui []) berisi anggota __proTo__ yang menunjuk ke objek metode yang sama dengan dorongan, terbalik, dll. (Array.prototype), bahwa objek array ini dapat menggunakan metode dorong, terbalik dan lainnya.
Instance Objek Fungsi
Salinan kode adalah sebagai berikut:
function base () {
this.id = "base"
}
Salinan kode adalah sebagai berikut:
var obj = basis baru ();
Apa hasil dari kode seperti itu? Model objek yang kita lihat di mesin JavaScript adalah:
Apa sebenarnya yang dilakukan operator baru? Bahkan, itu sangat sederhana, hanya melakukan tiga hal.
Salinan kode adalah sebagai berikut:
var obj = {};
obj .__ proto__ = base.prototype;
Base.call (OBJ);
Rantai prototipe
Rantai Prototipe: Ketika suatu properti atau metode diambil dari suatu objek, jika objek itu sendiri tidak memiliki properti atau metode seperti itu, ia akan mencari objek prototipe yang Anda kaitkan. Jika tidak ada prototipe, ia akan mencari pendahulu prototipe yang terkait dengan prototipe. Jika tidak ada lagi, terus mencari objek yang dirujuk oleh prototipe.prototype, dan seterusnya sampai prototipe ....... prototipe tidak ditentukan (prototipe objek tidak ditentukan), sehingga membentuk apa yang disebut "rantai prototipe".
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
bentuk fungsi () {
this.name = "bentuk";
this.toString = function () {
kembalikan nama ini;
}
}
fungsi twoshape () {
this.name = "2 bentuk";
}
fungsi segitiga (samping, tinggi) {
this.name = "segitiga";
this.side = sisi;
this.height = tinggi;
this.getarea = function () {
kembalikan ini.side*this.height/2;
}
}
Twoshape.prototype = bentuk baru ();
Triangle.prototype = twoshape baru ();
</script>
Di sini, entitas baru dibuat dengan bentuk konstruktor (), dan kemudian digunakan untuk menimpa prototipe objek.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
bentuk fungsi () {
this.name = "bentuk";
this.toString = function () {
kembalikan nama ini;
}
}
fungsi twoshape () {
this.name = "2 bentuk";
}
fungsi segitiga (samping, tinggi) {
this.name = "segitiga";
this.side = sisi;
this.height = tinggi;
this.getarea = function () {
kembalikan ini.side*this.height/2;
}
}
Twoshape.prototype = bentuk baru ();
Triangle.prototype = twoshape baru ();
Twoshape.prototype.constructor = twoshape;
Triangle.prototype.constructor = Triangle;
var my = segitiga baru (5,10);
my.getarea ();
my.tostring (); // segitiga
my.constructor; // segitiga (samping, tinggi)
</script>
Warisan prototipe
Prototipe Warisan: Pada akhir rantai prototipe, itu adalah objek prototipe yang ditunjuk oleh atribut prototipe konstruktor objek. Objek prototipe ini adalah leluhur dari semua objek, dan leluhur ini menerapkan metode yang harus dimiliki oleh semua objek seperti Tostring. Konstruktor bawaan lainnya, seperti fungsi, boolean, string, tanggal dan regexp, diwarisi dari leluhur ini, tetapi mereka masing-masing menentukan atribut dan metode mereka sendiri, sehingga keturunan mereka menunjukkan karakteristik klan masing-masing.
Dalam ecmascript, metode penerapan warisan dicapai dengan mengandalkan rantai prototipe.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
Function Box () {// Fungsi yang diwariskan disebut supertype (kelas induk, kelas dasar)
this.name = "jack";
}
Function Tree () {// Fungsi yang diwariskan disebut subtipe (subkelas, kelas turunan)
this.age = 300;
}
// mewarisi melalui rantai prototipe, tetapkan atribut prototipe subtipe
// kotak baru () akan menyerahkan informasi dalam konstruk kotak dan informasi dalam prototipe ke pohon
Tree.prototype = box baru (); // pohon mewarisi kotak dan membentuk rantai melalui prototipe.
var tree = pohon baru ();
Peringatan (Tree.name); // Jack Popt
</script>
Masalah dengan rantai prototipe: Meskipun rantai prototipe sangat kuat dan dapat digunakan untuk menerapkan warisan, ia juga memiliki beberapa masalah. Masalah terpenting berasal dari prototipe nilai yang berisi jenis referensi. Atribut prototipe yang berisi jenis referensi dibagikan oleh semua contoh; Inilah sebabnya mengapa atribut didefinisikan dalam konstruktor, bukan pada objek prototipe. Ketika warisan dicapai melalui prototipe, prototipe sebenarnya menjadi contoh dari jenis lain. Oleh karena itu, atribut instance asli menjadi atribut prototipe.
Saat membuat instance subtipe, argumen tidak dapat diteruskan ke konstruktor supertype. Bahkan, harus dikatakan bahwa tidak ada cara untuk meneruskan parameter ke konstruktor supertype tanpa mempengaruhi semua instance objek. Selain masalah yang baru saja dibahas karena dimasukkannya nilai jenis referensi dalam prototipe, jarang menggunakan rantai prototipe saja dalam praktiknya.
Chestnut lain:
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
Function Person (Name)
{
this.name = name; // atur properti objek
};
Person.prototype.company = "microsoft"; // atur properti prototipe
Person.prototype.sayhello = function () // metode prototipe
{
alert ("Halo, saya"+ this.name+ "dari"+ this.company);
};
var billgates = orang baru ("billgates"); // membuat objek orang
Billgates.sayhello (); // mewarisi konten prototipe dan output "Halo, saya Billgates of Microsoft"
var job = orang baru ("pekerjaan");
Jobs.comcany = "apple"; // Setel atribut perusahaan Anda sendiri untuk menutupi atribut perusahaan prototipe
Jobs.sayhello = function ()
{
alert ("hai," + this.name + "like" + this.company);
};
Jobs.sayhello (); // properti dan metode yang Anda ajukan sendiri, output "Hai, pekerjaan seperti apel"
Billgates.sayhello (); // Cakupan pekerjaan tidak mempengaruhi prototipe, billgates masih output
</script>
Lihat contoh rantai prototipe berikut:
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
function year () {
this.value = 21;
}
Year.prototype = {
Metode: function () {
}
};
fungsi hi () {
};
// Atur properti prototipe HI ke objek instance tahun
Hi.prototype = tahun baru ();
Hai.prototype.year = 'Hello World';
Hai.prototype.constructor = hai;
var test = hai baru (); // Buat instance baru dari HI
// rantai prototipe
tes [hai contoh]
Hai.prototype [contoh tahun]
{tahun: 'halo dunia'}
Year.prototype
{metode:…};
Object.prototype
{tostring: ...};
</script>
Dari contoh di atas, objek uji diwarisi dari HI.Prototipe dan tahun. Prototype; Oleh karena itu dapat mengakses metode metode prototipe tahun, dan pada saat yang sama dapat mengakses nilai properti instan
Atribut __ptoto__
Atribut __ptoto__ (tidak didukung oleh IE browser) adalah pointer ke objek prototipe dari instance. Fungsinya adalah untuk menunjuk ke konstruktor atribut prototipe dari konstruktor. Melalui dua atribut ini, Anda dapat mengakses properti dan metode dalam prototipe.
Contoh objek dalam JavaScript pada dasarnya terdiri dari serangkaian properti. Di antara properti ini, ada properti khusus yang tidak terlihat secara internal - __proto__. Nilai properti ini menunjuk ke prototipe instance objek. Contoh objek hanya memiliki prototipe yang unik.
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {// huruf besar, mewakili konstruktor
Box.prototype.name = "trigkit4"; // atribut prototipe
Box.prototype.age = "21";
Box.prototype.run = function () // metode prototipe
{
kembalikan this.name + this.age + 'belajar';
}
}
var box1 = box baru ();
var box2 = box baru ();
alert (box1.constructor); // buat atribut, Anda bisa mendapatkan konstruktor itu sendiri,
// Fungsinya harus diposisikan oleh pointer prototipe dan kemudian mendapatkan konstruktor itu sendiri
</script>
Perbedaan antara atribut __proTo__ dan atribut prototipe
Prototipe adalah properti berpemilik dalam objek fungsi.
__proto__ adalah properti implisit dari objek normal. Saat baru, itu akan menunjuk ke objek yang ditunjukkan oleh prototipe;
__ptoto__ sebenarnya merupakan atribut dari objek entitas tertentu, sedangkan prototipe adalah atribut milik konstruktor. __ptoto__ hanya dapat digunakan dalam lingkungan belajar atau men -debug.
Proses eksekusi mode prototipe
1. Pertama cari atribut atau metode dalam contoh konstruktor, dan jika demikian, segera kembali.
2. Jika tidak ada contoh konstruktor, buka objek prototipe dan segera kembalikan.
Objek prototipe
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {// huruf besar, mewakili konstruktor
Box.prototype.name = "trigkit4"; // atribut prototipe
Box.prototype.age = "21";
Box.prototype.run = function () // metode prototipe
{
kembalikan this.name + this.age + 'belajar';
}
}
var box1 = box baru ();
peringatan (box1.name); // trigkit4, nilai dalam prototipe
box1.name = "Lee";
waspada (box1.name); // lee, buka prinsipnya
var box2 = box baru ();
alert (box2.name); // trigkit4, nilai prototipe, tidak dimodifikasi oleh box1
</script>
Konstruktor
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
kotak fungsi () {
this.name = "bill";
}
Box.prototype.name = "trigkit4"; // atribut prototipe
Box.prototype.age = "21";
Box.prototype.run = function () // metode prototipe
{
kembalikan this.name + this.age + 'belajar';
}
var box1 = box baru ();
peringatan (box1.name); // tagihan, nilai dalam prototipe
box1.name = "Lee";
waspada (box1.name); // lee, buka prinsipnya
</script>
Singkatnya, mari kita selesaikan:
Salinan kode adalah sebagai berikut:
<type skrip = "Teks/JavaScript">
function person () {};
Person.prototype.name = "trigkit4";
Person.prototype.say = function () {
alert ("hi");
}
var p1 = orang baru (); // Prototipe adalah objek prototipe P1 dan P2
var p2 = orang baru (); // p2 adalah objek instantiated, dan ada atribut __proTo__ di dalamnya, menunjuk ke prototipe orang
console.log (p1.prototype); // tidak ditentukan, properti ini adalah objek dan tidak dapat diakses
console.log (person.prototype); // orang
console.log (person.prototype.constructor); // Ada juga pointer (properti konstruktor) di dalam objek prototipe yang menunjuk ke fungsi konstruktor
console.log (p1 .__ proto __); // Properti ini adalah pointer yang menunjuk ke objek prototipe prototipe
p1.say (); // instance dapat mengakses properti dan metode yang ditentukan pada objek prototipe
</script>
Model pabrik
Salinan kode adalah sebagai berikut:
fungsi createObject (name, use) {
var obj = objek baru ();
obj.name = nama;
obj.age = usia;
kembalikan obj;
}
Pola pabrik memecahkan masalah duplikasi skala besar dari objek yang instanasi, tetapi ada masalah lain, yaitu, tidak mungkin untuk mengetahui contoh objek mana mereka.
Menggunakan metode konstruktor tidak hanya memecahkan masalah instantiasi berulang, tetapi juga memecahkan masalah pengenalan objek.
Perbedaan antara menggunakan metode konstruktor dan pola pabrik adalah bahwa:
1. Buat objek (objek baru ()) yang tidak ditampilkan oleh metode konstruktor;
2. Langsung tetapkan atribut dan metode untuk objek ini
3. No Return Pernyataan
Ketika konstruktor digunakan dan konstruktor baru () digunakan, objek baru () dieksekusi di latar belakang;
Ini dalam tubuh fungsi mewakili objek yang berasal dari objek baru ()
1. Tentukan apakah properti dalam instance konstruktor atau dalam prototipe, Anda dapat menggunakan `hasownproperty ()` fungsi
2. Cara membuat literal digunakan untuk membuat atribut konstruktor tidak akan menunjuk ke instance, tetapi pada objek, dan cara untuk membuat konstruktor adalah sebaliknya.
Mengapa menunjuk ke objek? Karena box.prototype = {}; cara menulis ini sebenarnya adalah membuat objek baru.
Setiap kali fungsi dibuat, prototipe akan dibuat pada saat yang sama, dan objek ini akan secara otomatis mendapatkan atribut konstruktor
3. Jika itu adalah metode instan, instantiasi yang berbeda, alamat metode mereka berbeda dan unik.
4. Jika itu adalah metode prototipe, maka alamat mereka dibagikan