原型實例(Prototype)
原型模式:用原型實例指向建立對象的類,使用於建立新的對象的類共享原型對象的屬性和方法
7.1 語言中的原型
在javascript中的繼承是靠原型鏈實現的,那麼這就是Javascript中的原型模式把?
嗯,原型模式就是將原型對象指向建立對象的類,使這些類共享原型對象的方法與屬性。固然Javascript是基於原型鏈實現對象之間的繼承,這種繼承是基於一種對屬性或者方法的共享,而不是對屬性和方法的複製javascript
7.2 建立一個焦點圖
舉個例子:假設頁面中有不少的焦點圖(網頁中很常見的一種圖片輪播,切換效果),那麼咱們要實現這些焦點圖最好的方式就是經過建立對象來一一實現的,因此咱們就須要有一個焦點圖類,好比咱們把這個類定義爲 LoopImagesjava
// 圖片輪播類 var LoopImages = function(imgArr, container) { this.imagesArray = imgArr; // 輪播圖片數組 this.container = container; // 輪播圖片容器 this.createImage = function(){} // 建立輪播圖片 this.changeImage = function(){} // 切換下一章圖片 } // 咱們應該抽象出一個基類,讓不一樣特效類去繼承這個基類,而後對於差別化的需求經過重寫這些繼承下來的屬性或方法來解決,固然不一樣的子類之間可能存在不一樣的 // 結構樣式 // 上下滑動切換類 var SlideLoopImg = function(imgArr, container) { // 構造函數繼承圖片輪播類 LoopImages.call(this, imgArr, container); // 重寫繼承的切換下一張圖片的方法 this.changeImage = function(){ console.log('SlideLoopImg changeImage function'); } } // 漸隱切換類 var FadeLoopImg = function(imgArr, container, arrow) { LoopImages.call(this, imgArr, container); // 切換箭頭私有變量 this.arrow = arrow; this.changeImage = function(){ console.log('FadeLoopImg changeImage function'); } }
// 咱們建立一個顯隱輪播圖片測試實例很容易 // 實例化一個漸隱切換圖片類 var fadeImg = new FadeLoopImg([ '01.jpg', '02.jpg', '03.jpg', '04.jpg' ],'slide', [ 'left.jpg', 'right.jpg' ]); fadeImg.changeImage(); // FadeLoopImg changeImage function
7.3 最優的解決方案
// 圖片輪播類 var LoopImages = function(imgArr, container) { this.imagesArray = imgArr; // 圖片輪播組 this.container = container; // 輪播圖片容器 } LoopImages.prototype = { // 建立輪播圖片 createImage : function() { console.log('LoopImages createImage function'); }, // 切換下一張圖片 changeImage : function() { console.log('LoopImages changeImage function'); } } // 上下滑動切換類 var SlideLoopImg = function(imgArr, container) { // 構造函數繼承圖片輪播類 LoopImages.call(this, imgArr, container); } SlideLoopImg.prototype.changeImage = function() { console.log('SlideLoopImg changeImage function'); } // 漸隱切換類 var FadeLoopImg = function(imgArr, container, arrow) { LoopImages.call(this, imgArr, container); // 切換箭頭私有變量 this.arrow = arrow; } FadeLoopImg.prototype = new LoopImages(); FadeLoopImg.prototype.changeImage = function() { console.log('FadeLoopImage changeImage function'); } // 測試用例 console.log(fadeImg.container); // slide fadeImg.changeImage(); // FadeLoopImage changeImage function
7.4 原型的拓展
你知道關於原型對象的一個特色嗎?
原型對象是一個共享的對象,那麼不管是父類的實例對象或者是子類的繼承,都是都它的一個指向引用,因此原型對象纔會被共享,既然被共享,那麼對於原型對象的拓展,不管是子類仍是父類的實例對象都會繼承下來。數組
// 測試代碼 LoopImages.prototype.getImageLength = function() { return this.imagesArray.length; } FadeLoopImg.prototype.getContainer = function() { return this.container; } console.log(fadeImg.getImageLength()); // 4 console.log(fadeImg.getContainer()); // slide
7.5 原型繼承
/***** * 基於已經存在的模版對象克隆出新對象的模式 * arguments[0], arguments[1], argument[2]: 參數1, 參數2,參數3 表示模版對象 * 注意。這裏對模版引用類型的屬性實質上進行了淺複製(引用類型屬性共享) * 固然根據需求能夠自行深複製 *****/ function prototypeExtend() { var F = function() {}, // 緩存類,爲實例化返回對象臨時建立 args = arguments, // 模版對象參數序列 i = 0, len = args.length; for(; i < len; i++){ // 遍歷每一個模版對象中的屬性 for( var j in args[i]) { // 將這些屬性複製到緩存類的原型中 F.prototype[j] = args[i][j]; } } // 返回緩存類的一個實例 return new F(); }
好比企鵝遊戲中咱們建立一個企鵝基類,只是提供了一些動做模版對象,咱們就能夠經過實現對這些模版對象的繼承來建立一個企鵝實例對象緩存
var penguin = prototypeExtend({ speed : 20, swim : function(){ console.log('游泳速度' + this.speed); } },{ run : function(speed) { console.log('奔跑速度' + speed); } },{ jump : function() { console.log('跳躍動做'); } }) // 既然經過prototypeExtend 建立的是一個對象, 咱們就無需在再用new去建立的實例對象,咱們能夠直接使用這個對象 penguin.swim(); // 游泳速度 20 penguin.run(10); // 奔跑速度 10 penguin.jump(); // 跳躍動做