原型实例(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(); // 跳跃动做