Ya, fungsi pertama tidak memiliki hubungan dengan instance objek dari fungsi konstruktor itu , Anda dapat menganggapnya sebagai 'metode statis' .
Dalam fungsi JavaScript adalah objek kelas satu , yang berarti Anda dapat memperlakukannya sama seperti objek apa pun, dalam hal ini, Anda hanya menambahkan properti ke objek fungsi .
Fungsi kedua, saat Anda memperluas prototipe fungsi konstruktor, itu akan tersedia untuk semua instance objek yang dibuat dengan newkata kunci, dan konteks di dalam fungsi tersebut ( thiskata kunci) akan merujuk ke instance objek aktual di mana Anda menyebutnya.
Pertimbangkan contoh ini:
// constructor functionfunctionMyClass(){var privateVariable;// private member only available within the constructor fnthis.privilegedMethod =function(){// it can access private members//..};}// A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instanceMyClass.staticMethod =function(){};MyClass.prototype.publicMethod =function(){// the 'this' keyword refers to the object instance// you can access only 'privileged' and 'public' members};var myObj =newMyClass();// new object instance
myObj.publicMethod();MyClass.staticMethod();
Tetapi mengapa Function.prototype.method == Function.method?
Raghavendra
1
@Raghavendra bukan
Zorgatone
1
@Rencanakan tautan Anda sudah mati
Eugen Sunic
19
Ketika Anda membuat lebih dari satu instance dari MyClass, Anda hanya akan memiliki hanya satu instance publicMethod dalam memori tetapi dalam kasus privilegeMethod Anda akhirnya akan membuat banyak instance dan staticMethod tidak memiliki hubungan dengan instance objek.
Itu sebabnya prototipe menghemat memori.
Juga, jika Anda mengubah properti objek induk, apakah properti yang sesuai anak itu belum diubah, itu akan diperbarui.
Untuk pelajar visual, ketika mendefinisikan fungsi tanpa .prototype
ExampleClass=function(){};ExampleClass.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// >> output: `called from func def.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// >> error! `someInstance.method is not a function`
Dengan kode yang sama, jika .prototypeditambahkan,
ExampleClass.prototype.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// > error! `ExampleClass.method is not a function.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// > output: `Called from instance`
Untuk membuatnya lebih jelas,
ExampleClass=function(){};ExampleClass.directM =function(){}//M for methodExampleClass.prototype.protoM =function(){}var instanceOfExample =newExampleClass();ExampleClass.directM();✓ works
instanceOfExample.directM(); x Error!ExampleClass.protoM(); x Error!
instanceOfExample.protoM();✓ works
**** Catatan untuk contoh di atas, someInstance.method () tidak akan dieksekusi karena,
ExampleClass.method () menyebabkan kesalahan & eksekusi tidak dapat dilanjutkan.
Tetapi demi ilustrasi & pemahaman yang mudah, saya telah menjaga urutan ini. ****
Hasil yang dihasilkan dari chrome developer console&
Klik tautan jsbin di atas untuk melangkah melalui kode.
Toggle bagian komentar dengan +JS Bin
Lihat bagaimana statickata kunci digunakan untuk mendeklarasikan metode statis isPerson.
Untuk membuat objek Personkelas.
const aminu = new Person("Aminu", "Abubakar");
Menggunakan metode statis isPerson.
Person.isPerson(aminu); // will return true
Menggunakan metode instance sayHi.
aminu.sayHi(); // will return "Hi Aminu"
CATATAN: Kedua contoh pada dasarnya sama, JavaScript tetap merupakan bahasa tanpa kelas. Yang classdiperkenalkan dalam ES6 terutama adalah gula sintaksis atas model pewarisan berbasis prototipe yang ada.
"Dalam ES6" Anda hanya menggambarkan gula sintaks. Ini bukan cara "ES2015" (tolong semua orang berhenti menggunakan ES6 menggunakan istilah ES2015 yang tepat) untuk melakukannya. Ini hanyalah cara lain untuk melakukannya dan menurut saya cara yang salah.
K - Keracunan dalam SO tumbuh.
2
@KarlMorrison Aminu tidak menulis "cara melakukannya", Anda hanya menulis sendiri dan mengambil pengecualian untuk itu. Maksud Anda mungkin adil tentang ES6 vs ES2015 tetapi dalam percakapan orang sering menggunakan konvensi yang lebih pendek untuk efisiensi, jadi saya pikir menghapusnya dari menulis tidak mungkin atau pasti disarankan.
wuliwong
Terima kasih atas bagian ES6 dari jawaban Anda; yang banyak mengklarifikasi, terutama bila dikombinasikan dengan 2 jawaban "publik + istimewa" di atas. Namun saya benar - benar bingung dengan obj.constructor === Personmenjadi truecontoh Anda ... Whaaaat? Bagaimana konstruktor instance ===kelas dengan kelas itu sendiri ...? (Itu seperti mengatakan subset dari himpunan adalah himpunan itu sendiri, dll ...)
Andrew
Ohhh ... apakah ini semua yang dapat dikatakan bahwa secara literal, konstruktor adalah semua yang benar-benar dimiliki oleh kelas JS pada akhirnya? Segala sesuatu yang lain baik ditumpuk ke dalam konstruktor atau benar-benar sebuah konstruksi statis yang terisolasi dari kelas kecuali dengan nama / konsep (dan seperti tersirat "ini" yang tersedia jelas)? (Jadi, yang saya pikir adalah himpunan bagian dari himpunan sebenarnya bukan himpunan bagian.)
Ketika Anda membuat lebih dari satu instance dari MyClass, Anda hanya akan memiliki hanya satu instance publicMethod dalam memori tetapi dalam kasus privilegeMethod Anda akhirnya akan membuat banyak instance dan staticMethod tidak memiliki hubungan dengan instance objek.
Itu sebabnya prototipe menghemat memori.
Juga, jika Anda mengubah properti objek induk, apakah properti yang sesuai anak itu belum diubah, itu akan diperbarui.
sumber
Untuk pelajar visual, ketika mendefinisikan fungsi tanpa
.prototype
Dengan kode yang sama, jika
.prototype
ditambahkan,Untuk membuatnya lebih jelas,
**** Catatan untuk contoh di atas, someInstance.method () tidak akan dieksekusi karena,
ExampleClass.method () menyebabkan kesalahan & eksekusi tidak dapat dilanjutkan.
Tetapi demi ilustrasi & pemahaman yang mudah, saya telah menjaga urutan ini. ****
Hasil yang dihasilkan dari
chrome developer console
& Klik tautan jsbin di atas untuk melangkah melalui kode. Toggle bagian komentar dengan +JS Bin
ctrl/
sumber
Ya, yang pertama
static method
disebut jugaclass method
, sedangkan yang kedua adalahinstance method
.Perhatikan contoh-contoh berikut, untuk memahaminya secara lebih rinci.
Dalam ES5
Dalam kode di atas,
isPerson
adalah metode statis, sedangkansayHi
metode instan dariPerson
.Di bawah ini adalah cara membuat objek dari
Person
konstruktor.var aminu = new Person("Aminu", "Abubakar");
Menggunakan metode statis
isPerson
.Person.isPerson(aminu); // will return true
Menggunakan metode instance
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
Dalam ES6
Lihat bagaimana
static
kata kunci digunakan untuk mendeklarasikan metode statisisPerson
.Untuk membuat objek
Person
kelas.const aminu = new Person("Aminu", "Abubakar");
Menggunakan metode statis
isPerson
.Person.isPerson(aminu); // will return true
Menggunakan metode instance
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
CATATAN: Kedua contoh pada dasarnya sama, JavaScript tetap merupakan bahasa tanpa kelas. Yang
class
diperkenalkan dalam ES6 terutama adalah gula sintaksis atas model pewarisan berbasis prototipe yang ada.sumber
obj.constructor === Person
menjaditrue
contoh Anda ... Whaaaat? Bagaimana konstruktor instance===
kelas dengan kelas itu sendiri ...? (Itu seperti mengatakan subset dari himpunan adalah himpunan itu sendiri, dll ...)