本文實例總結了JavaScript類的繼承操作。分享給大家供大家參考,具體如下:
創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網(wǎng)站設計、網(wǎng)站建設、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的興海網(wǎng)站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡建設合作伙伴!
一、類式繼承
首先要做的是創(chuàng)建構造函數(shù)。按慣例,其名稱就是類名,首字母應該大寫。在構造函數(shù)中,創(chuàng)建實例屬性要用關鍵字this
。類的方法則被添加到prototype
對象中。要創(chuàng)建該類的實例,只需結合關鍵字new
調用這構造函數(shù)即可。
/* Class Person. */ function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; } var reader = new Person('John Smith'); reader.getName();
二、原型鏈
JavaScript的每個對象都有一個名為prototype
的屬性,這個屬性要么指向另一個對象,要么是null.在訪問對象的某個成員時,如果這個成員未見于當前對象,那么就會到prototype所指的對象中去查找。如果還是沒有找到,那么就會沿著原型鏈逐一訪問每個原型對象,直到找到這個成員。這意味著讓一個類繼承另一個類,只需將子類的prototype
設置為超類的一個實例即可。
為了讓Author繼承Person,必須手工將Author的prototype
設置為Person的一個實例。最后一步是將prototype
的construct
屬性重設為Author(因為prototype
屬性設置為Person的實例)時,其construct
屬性被抹除了。
function Author(name, books) { Person.call(this, name); // Call the superclass' constructor in the scope of this. this.books = books; // Add an attribute to Author. } Author.prototype = new Person(); // Set up the prototype chain. Author.prototype.constructor = Author; // Set the constructor attribute to Author. Author.prototype.getBooks = function() { // Add a method to Author. return this.books; }; var author = []; author[0] = new Author('Dustin Diaz', ['JavaScript Design Patterns']); author[1] = new Author('Ross Harmes', ['JavaScript Design Patterns']); console.log(author[1].getName()); console.log(author[1].getBooks());
三、extend函數(shù)
為了簡化類的聲明,可以把派生子類的整個過程包裝在一個名為extend的函數(shù)中。它的作用與其他語言的extend
關鍵字類似,即基于一個給定的類的結構創(chuàng)建一個新的類:
function extend(subClass, superClass) { var F = function() {}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; }
其實所做的事與之前的是一樣的。它先設置了prototype
,然后再將其constructor
重設為恰當?shù)闹怠2⑶抑虚g利用了一個空函數(shù),這樣就可以避免創(chuàng)建超類的實例。使用extend
繼承的寫法:
function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; } /* Class Author. */ function Author(name, books) { Person.call(this, name); this.books = books; } extend(Author, Person); Author.prototype.getBooks = function() { return this.books; };
但上面的存在一個問題就是超類Person的名稱被固化在Author類的聲明當中。更普世性的做法應該像下面這樣:
/* Extend function, improved. */ function extend(subClass, superClass) { var F = function() {}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; subClass.superclass = superClass.prototype; if(superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; } } /* Class Author. */ function Author(name, books) { Author.superclass.constructor.call(this, name); this.books = books; } extend(Author, Person); Author.prototype.getBooks = function() { return this.books; }; Author.prototype.getName = function() { var name = Author.superclass.getName.call(this); return name + ', Author of ' + this.getBooks().join(', '); };
這個extend
改進之后,多了一個superclass的屬性,這個屬性可以弱化Author和Person之間的耦合。extend
后面三行用來確保超類的construtor已經(jīng)被正確設置了。有了superclass的屬性,就可以直接調用超類中的方法。這在既要重新定義超類的某個方法而又想訪問其在超類中的實現(xiàn)時可以派上用場。例如,為了用一個新的getName的方法重新定義Person類中的同名方法,你可以先用Author.superclass.getName
獲得作者的名字,然后再次基礎上添加新的信息。
四、原型繼承
原型式繼承與類式繼承截然不同,我們在學習他的時候,最好忘記自己關于類和實例的一切知識,只從對象的角度來思考。使用原型式繼承時,并不需要用類來定義對象的結構,只需直接創(chuàng)建一個對像就可以。這個對象隨后可以被新的對象使用,該對象被稱為原型對象。
下面使用原型對象來重新設計上面Person和Author:
var Person = { name: 'default name', getName: function() { return this.name; } }; var reader = clone(Person); alert(reader.getName()); // This will output 'default name'. reader.name = 'John Smith'; alert(reader.getName()); // This will now output 'John Smith'.
clone
函數(shù)可以用來創(chuàng)建新的類Person對象,創(chuàng)建一個空對象,并且該對象的原型對象被設置為person。當新對象中找不到某個方法時就會在原型對象中查找。
你不必去為了創(chuàng)建Author而定義一個Person子類,只要執(zhí)行一次克隆就可以:
var Author = clone(Person); Author.books = []; // Default value. Author.getBooks = function() { return this.books; }
然后你可以重定義該克隆中的方法和屬性。可以修改Person的默認值。也可以添加新的屬性和方法。這樣一來就創(chuàng)建了一個新的原型對象,你可以將其用于創(chuàng)建新的Author對象:
var author = []; author[0] = clone(Author); author[0].name = 'Dustin Diaz'; author[0].books = ['JavaScript Design Patterns']; author[1] = clone(Author); author[1].name = 'Ross Harmes'; author[1].books = ['JavaScript Design Patterns']; author[1].getName(); author[1].getBooks();
clone函數(shù)的寫法:
function clone(object) { function F() {} F.prototype = object; return new F; }
五、原型繼承和類式繼承之間的比較
可以自己去總結、
從內存,適用范圍,優(yōu)缺點等方面去分析
六、摻元類
有一種重用代碼的方法不需要用到嚴格的繼承,如果想把一個函數(shù)運用到多個類當中,可以通過擴充的方法讓這些類共享函數(shù)。其實際大體做法就是:先創(chuàng)建一個包含各種通用的方法類,然后再擴充其他類,這種包含通用方法類稱為摻元類,他們通常不會被實例化和直接調用,其存在的目的是向其他類提供自己的方法。
var Mixin = function() {}; Mixin.prototype = { serialize: function() { var output = []; for(key in this) { output.push(key + ': ' + this[key]); } return output.join(', '); } }; augment(Author, Mixin); var author = new Author('Ross Harmes', ['JavaScript Design Patterns']); var serializedString = author.serialize(); function augment(receivingClass, givingClass) { for(methodName in givingClass.prototype) { if(!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } }
但是有時候你并不需要所有的方法,因此我們還需要提供額外的參數(shù)來選擇我們所需要的方法。如果不提供,那就全部復制。
function augment(receivingClass, givingClass) { if(arguments[2]) { // Only give certain methods. for(var i = 2, len = arguments.length; i < len; i++) { receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } } else { // Give all methods. for(methodName in givingClass.prototype) { if(!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } }
更多關于JavaScript相關內容還可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數(shù)據(jù)結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數(shù)學運算用法總結》
希望本文所述對大家JavaScript程序設計有所幫助。
網(wǎng)站欄目:JavaScript類的繼承操作實例總結
文章源于:http://m.newbst.com/article34/pgcese.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、網(wǎng)站排名、微信小程序、靜態(tài)網(wǎng)站、微信公眾號、網(wǎng)站內鏈
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)