Contoh dalam artikel ini memperkenalkan 6 cara untuk melaksanakan warisan dalam JavaScript dan berkongsi dengan anda untuk rujukan anda Kandungan khusus adalah seperti berikut
1. [Pewarisan Rantaian Prototaip] Intipati pelaksanaan adalah untuk menulis semula objek prototaip dan menggantikannya dengan contoh jenis baharu. Sebenarnya, bukan sifat pembina prototaip SubType yang telah ditulis semula, tetapi prototaip SubType menghala ke objek lain - prototaip SuperType, dan sifat pembina objek prototaip ini menghala ke SuperType
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //继承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function(){ return this.subproperty; } var instance = new SubType(); alert(instance.getSuperValue());//true
[Nota 1] Tentukan kaedah dengan teliti, dan kod untuk menambah kaedah pada prototaip mesti diletakkan selepas pernyataan yang menggantikan prototaip
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //继承了SuperType SubType.prototype = new SuperType(); //添加了新方法 SubType.prototype.getSubValue = function(){ return this.subproperty; } //重写超类型的方法 SubType.prototype.getSuperValue = function(){ return false; } var instance = new SubType(); alert(instance.getSuperValue());//false
[Nota 2] Apabila melaksanakan pewarisan melalui rantaian prototaip, anda tidak boleh menggunakan literal objek untuk mencipta kaedah prototaip akan menimpa rantai prototaip
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //继承了SuperType SubType.prototype = new SuperType(); //使用字面量方法添加新方法会导致上一行代码无效 SubType.prototype = { getSubValue : function(){ return this,subproperty; }, someOtherMethod : function(){ return false; } }; var instance = new SubType(); alert(instance.getSuperValue());//error
[Kelemahan 1] Apabila membuat contoh subjenis, parameter tidak boleh dihantar kepada pembina superjenis
[Kelemahan 2] Sifat prototaip yang mengandungi nilai jenis rujukan akan dikongsi oleh semua kejadian
function SuperType(){ this.colors = ['red','blue','green']; } function SubType(){} //继承了SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push('black'); alert(instance1.colors);//'red,blue,green,black' var instance2 = new SubType(); alert(instance2.colors);//'red,blue,green,black'
2. [Warisan pembina yang dipinjam (juga dipanggil objek palsu atau warisan klasik)] memanggil pembina supertype di dalam pembina subjenis, jadi dengan menggunakan kaedah apply() dan call() Pembina juga boleh dilaksanakan pada objek yang baru dicipta pada masa hadapan
function SuperType(){ this.colors = ['red','blue','green']; } function SubType(){ //继承了SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push('black'); alert(instance1.colors);//'red,blue,green,black' var instance2 = new SubType(); alert(instance2.colors);//'red,blue,green'
[Kelebihan] Lulus parameter
function SuperType(name){ this.name = name; } function SubType(){ //继承了SUperType,同时还传递了参数 SuperType.call(this,"Nicholas"); //实例属性 this.age = 29; } var instance = new SubType(); alert(instance.name);//"Nicholas" alert(instance.age);//29
[Nota] Untuk memastikan bahawa pembina SuperType tidak mengatasi sifat subjenis, anda boleh menambah sifat yang harus ditakrifkan dalam subjenis selepas memanggil pembina supertype
function SuperType(name){ this.name = name; this.age = 30; } function SubType(){ //实例属性 this.age = 29; //继承了SUperType,同时还传递了参数 SuperType.call(this,"Nicholas"); } var instance = new SubType(); //实例属性被重写为SuperType构造函数的属性 alert(instance.age);//30
[Kelemahan 1] Penggunaan semula fungsi tidak dapat dicapai
[Kelemahan 2] Kaedah yang ditakrifkan dalam prototaip jenis super juga tidak kelihatan kepada subjenis Akibatnya, semua jenis hanya boleh menggunakan corak pembina
3. [Warisan gabungan (juga dipanggil warisan pseudo-klasik)] Model warisan yang menggabungkan teknologi pembina rantaian prototaip dan peminjaman untuk memanfaatkan kekuatan kedua-duanya. Idea di sebaliknya ialah menggunakan rantaian prototaip untuk mencapai pewarisan sifat dan kaedah prototaip, dan untuk mencapai pewarisan sifat contoh dengan meminjam pembina. Dengan cara ini, penggunaan semula fungsi dicapai dengan mentakrifkan kaedah pada prototaip, dan setiap contoh boleh dijamin mempunyai atributnya sendiri, menjadikannya corak warisan yang paling biasa digunakan dalam JavaScript.
function SuperType(name){ this.name = name; this.colors = ['red','blue','green']; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name,age){ //继承属性 SuperType.call(this,name); this.age = age; } //继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); } var instance1 = new SubType("Nicholas",29); instance1.colors.push("black"); alert(instance1.colors);//'red,blue,green,black' instance1.sayName();//"Nicholas" instance1.sayAge();//29 var instance2 = new SubType("Greg",27); alert(instance2.colors);//'red,blue,green' instance2.sayName();//"Greg" instance2.sayAge();//27
[Kelemahan] Dalam apa jua keadaan, pembina supertype akan dipanggil dua kali: sekali apabila mencipta prototaip subjenis, dan sekali di dalam pembina subjenis. Subjenis akhirnya akan mengandungi semua sifat contoh objek supertype, tetapi perlu mengatasi sifat ini apabila pembina subjenis dipanggil.
function SuperType(name){ this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); // 第二次调用SuperType() this.age = age; } SubType.prototype = new SuperType(); //第一次调用SuperType() SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); };
4. [Warisan Prototaip] Menggunakan prototaip, anda boleh mencipta objek baharu berdasarkan objek sedia ada tanpa perlu mencipta jenis tersuai. Pada asasnya, object() melakukan salinan cetek objek yang dihantar ke dalamnya.
[Nota] Warisan prototaip memerlukan mesti ada objek yang boleh digunakan sebagai asas objek lain Jika terdapat objek sedemikian, anda boleh menghantarnya ke fungsi objek(), dan kemudian mengubah suai objek yang diperoleh mengikut tertentu memerlukan
function object(o){ function F(){}; F.prototype = o; return new F(); } var person = { name: "Nicholas", friends: ["Shelby","Court","Van"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"
【4.1】【Kaedah Object.create()】: Kaedah Object.create() baharu ECMAScript5 menyeragamkan warisan prototaip. Kaedah ini menerima dua parameter: objek untuk digunakan sebagai prototaip objek baharu dan (sebagai pilihan) objek untuk menentukan sifat tambahan untuk objek baharu. Apabila parameter dimasukkan, kaedah Object.create() dan object() berkelakuan sama
function object(o){ function F(){}; F.prototype = o; return new F(); } var person = { name: "Nicholas", friends:["Shelby","Court","Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"
[Nota] Parameter kedua kaedah Object.create() mempunyai format yang sama seperti parameter kedua kaedah Object.defineProperties(): setiap sifat ditakrifkan melalui deskriptornya sendiri. Mana-mana harta yang dinyatakan dengan cara ini mengatasi sifat nama yang sama pada objek prototaip.
var person = { name: "Nicholas", friends:["Shelby","Court","Van"] }; var anotherPerson = Object.create(person,{ name: { value: "Greg" } }); alert(anotherPerson.name);//"Greg"
【4.2】Serasi dengan kaedah Object.create() dalam pelayar versi rendah
if(typeof Object.create != "function"){ (function(){ var F = function(){}; Object.create = function(o){ if(arguments.length > 1){ throw Error('Second argument noe supported'); } if(o === null){ throw Error("Cannot set a null [[Prototype]]"); } if(typeof o != 'Object'){ throw TypeError("Arguments must be an object"); } F.prototype = o; return new F(); } })(); }
5. [Pewarisan Parasit] Buat fungsi yang hanya digunakan untuk merangkum proses pewarisan objek yang sama
[Kelemahan] Penggunaan semula fungsi tidak boleh dicapai
function object(o){ function F(){}; F.prototype = o; return new F(); } function createAnother(original){ var clone = object(original);//通过调用函数创建一个新对象 clone.sayHi = function(){ //以某种方式来增强这个对象 alert("hi"); }; return clone;//返回这个对象 } var person = { name: "Nicholas", friends: ["Shelby","Court","Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi();//"hi"
6. [Warisan Gabungan Parasit] Warisi sifat dengan meminjam pembina, dan mewarisi kaedah melalui bentuk hibrid rantaian prototaip. Idea asas di sebalik ini ialah daripada memanggil pembina supertype untuk menentukan prototaip subjenis, semua yang diperlukan ialah salinan prototaip supertype. Pada asasnya, anda menggunakan warisan parasit untuk mewarisi daripada prototaip supertype dan kemudian memberikan hasilnya kepada prototaip subjenis. Warisan gabungan parasit ialah paradigma warisan yang paling ideal untuk jenis rujukan.
//这个例子中的高效率体现在它只调用了一次Super构造函数,并且因此避免了在SubType.prototype上面创建不必要的、多余的属性。与此同时,原型链还能保持不变。 function object(o){ function F(){}; F.prototype = o; return new F(); } function inheritPrototype(subType,superType){ var prototype = object(superType.prototype);//创建对象 prototype.constructor = subType;//增强对象 subType.prototype = prototype;//指定对象 } function SuperType(name){ this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age = age; } inheritPrototype(SubType,SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }
Di atas ialah keseluruhan kandungan artikel ini, cara untuk melaksanakan warisan dalam JavaScript, terima kasih semua kerana membaca, dan editor akan terus bekerja keras!