Kaedah penulisan dalam pengaturcaraan lanjutan adalah seperti berikut
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
}
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
Jadi jika saya menulisnya seperti ini, adakah ia sama sahaja?
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
Person.prototype.getName = function(){
return this.name;
}
}
Cara penulisan kedua akan melaksanakan operasi pada prototaip setiap kali kejadian dibuat! Intinya ialah operasi ini tidak bermakna, dan kaedah ini adalah sama untuk setiap kejadian.
Dalam kaedah pertama, apabila prototaip ditulis di luar pembina, masalah definisi berulang atau peruntukan memori boleh diselesaikan secara formal dan melalui peruntukan memori.
Sepadan dengan cara penulisan pertama dalam ingatan Tidak kira berapa banyak kejadian yang anda buat, setiap kejadian hanya menduduki nama, umur, pekerjaan dan pelajaran. Hanya terdapat satu salinan getName dalam ingatan, dikongsi oleh semua kejadian; cara kedua penulisan, Setiap contoh yang baru dibuat akan memperuntukkan ruang tambahan (tindanan) untuk melaksanakan definisi prototaip.
Perbezaan adalah sangat besar Setelah kelas fungsi ditakrifkan, sifat pembina lalainya adalah dirinya sendiri, dan contohnya akan mengembalikan nilai ini apabila mengakses sifat pembina.
function Person() {};
console.log(Person.prototype.constructor); // Person
var p = new Person();
console.log(p.constructor); // Person 表示p的構(gòu)造函數(shù)是Person類
Mengapa anda perlu mentakrifkan pembina dalam kaedah 1 Kerana ia menetapkan semula prototaip Jika anda tidak mentakrifkan pembina (Person.prototype = {getName: function() {}}
) , maka di atas Dalam contoh, nilai pulangan p.constructor
akan menjadi Object
, iaitu, pembina p ialah Object, yang jelas tidak konsisten dengan fakta . Person.prototype = {getName: function() {}}
),那么上例中p.constructor
返回值將是 Object
, 即p的構(gòu)造函數(shù)是Object,顯然與事實不符。
方法1更明智的做法是不要重新給prototype賦值,只為prototype添加我們需要的屬性getName, 改為 Person.prototype.getName = function() {return this.name;}
Person.prototype.getName = function() {return this. name;} code>, iaitu kaedah takrifan dalam kaedah kedua, ditulis dengan cara ini supaya ia tidak akan mengatasi atribut lalai prototaip. #????#
首先,你應該搞清楚js中的原型,在js中,原型指的是構(gòu)造函數(shù)的prototype屬性的值,由構(gòu)造函數(shù)創(chuàng)建出來的實例會自動鏈接到原型對象也就是其構(gòu)造函數(shù)的prototype屬性上。
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
}
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
這個寫法中,Person為構(gòu)造函數(shù),可以創(chuàng)建出一個實例對象,
var p=new Person();
然后p可以繼承原型中的屬性,在原型中constructor指向的是當前的構(gòu)造函數(shù)
你的寫法可以理解為在構(gòu)造函數(shù)中給原型的getname屬性賦值了一個函數(shù)
Cara penulisan dahulu menulis semula prototaip, dan cara penulisan anda hanya menambah kaedah pada prototaip. Kedua-duanya adalah cara yang berbeza
Mengikut cara anda menulisnya, ruang storan akan diperuntukkan semula kepada contoh semasa setiap proses instantiasi Salah satu maksud corak prototaip ialah semua kejadian boleh berkongsi atribut dan kaedah pada prototaip, walaupun berbuat demikian sahaja mempunyai kelemahan. . Perkara kedua ialah saya masih lebih suka menulis objek objek prototaip secara literal Saya secara peribadi berpendapat bahawa satu lebih intuitif, dan yang kedua adalah kondusif untuk penyelenggaraan. Seperti berikut:
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
Pastikan anda menulis atribut pembina, jika tidak, ralat penunjuk akan berlaku Pada masa ini, objek prototaip ditulis semula Jika atribut ini tidak dinyatakan, rantai prototaip tidak akan dapat memainkan peranannya.
Rantai prototaip tidak sempurna, ia mengandungi dua masalah berikut.
Soalan 1: Apabila rantai prototaip mengandungi prototaip nilai jenis rujukan, nilai jenis rujukan akan dikongsi oleh semua kejadian;
Masalah 2: Apabila mencipta subjenis (seperti mencipta instance Son), parameter tidak boleh dihantar kepada pembina supertype (seperti Father).
Memandangkan perkara ini, pada praktiknya rantai prototaip jarang digunakan secara bersendirian.
Untuk tujuan ini, akan ada beberapa percubaan di bawah untuk mengimbangi kekurangan rantaian prototaip.
Untuk menyelesaikan dua masalah di atas dalam rantai prototaip, kami mula menggunakan teknologi yang dipanggil meminjam pembina (pembina mencuri) (juga dipanggil warisan klasik).
Idea asas: panggil pembina supertype di dalam pembina subjenis.
function Father(){
this.colors = ["red","blue","green"];
}
function Son(){
Father.call(this);//繼承了Father,且向父類型傳遞參數(shù)
}
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"
var instance2 = new Son();
console.log(instance2.colors);//"red,blue,green" 可見引用類型值是獨立的
Jelas sekali, meminjam pembina menyelesaikan dua masalah utama rantaian prototaip dalam satu kejadian:
Pertama, ia memastikan kebebasan nilai jenis rujukan dalam rantaian prototaip dan tidak lagi dikongsi oleh semua keadaan;
Kedua, semasa membuat subjenis, anda juga boleh menghantar parameter kepada jenis induk.
Berikutan ini, jika anda hanya meminjam pembina, anda tidak akan dapat mengelakkan masalah corak pembina - kaedah semuanya ditakrifkan dalam pembina, jadi penggunaan semula fungsi tidak tersedia dan Kaedah jenis super ditakrifkan dalam (seperti Bapa) juga tidak dapat dilihat oleh subjenis. Memandangkan ini, teknik peminjaman pembina jarang digunakan.
Untuk maklumat lanjut, sila rujuk rantai prototaip dan warisan JS anda menyukainya, sila berikan ibu jari dan sokongnya, terima kasih!