1、模式定义
原型模式,让原型实例指向一个类,使这个类能够共享(不是复制)原型对象的属性和方法。
2、一点说明
我们已经知道,基于原型链(原型模式)可以实现JavaScript中的继承关系,这种继承是对父级属性和方法的共享,而不是复制。可以说,原型模式是JavaScript语言的灵魂,在JavaScript面向对象编程思想或设计模式中,很多都是基于原型模式来实现的。
3、一段普通的代码
// 轮播图 基类
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);
// 覆写 changeImage() 方法
this.changeImage = function(){
console.log('上下滑动轮播');
}
};
// 渐隐切换的轮播图
var FadeLoopImg = function(imgArr, container, arrow){
LoopImages.call(this,imgArr,container);
// 新属性
this.arrow = arrow;
// 覆写 changeImage() 方法
this.changeImage = function(){
console.log('渐隐切换轮播');
}
}
// 测试一下
var fadeImg = new FadeLoopImg([
'01.png',
'02.png',
'03.png'
], 'slide', ['left.png', 'right.png']);
fadeImg.changeImage();
4、使用 原型模式 对上述代码进行优化
原型模式就是把可复用的、可共享的、可能耗时较多的方法,从基类中提取出来放到基类的原型链中。如此,当子类通过组合继承或者寄生组合式继承的方式去实现继承时,就可以共享这些方法。基于原型模式,优化后的代码如下:
// 基类
var LoopImages = function(imgArr,container){
this.imagesArray = imgArr;
this.container = container;
}
// 把基类中的方法提取出来,放到原型链中去
LoopImages.prototype = {
createImage: function(){
console.log('LoopImages');
},
changeImage: function(){
console.log('切换');
}
}
// 封装上下滑动的轮播类,并覆写changeImage()方法
var SlideLoopImg = function(imgArr,container){
LoopImages.call(this,imgArr,container);
}
SlideLoopImg.prototype = new LoopImages();
SlideLoopImg.prototype.changeImage = function(){
console.log('上下切换');
}
// 封装渐隐切换的轮播类,并覆写changeImage()方法
var FadeLoopImg = function(imgArr,container,arrow){
LoopImages.call(this,imgArr,container);
}
FadeLoopImg.prototype = new LoopImages();
FadeLoopImg.prototype.changeImage = function(){
console.log('渐隐切换');
}
// 对轮播基类的扩展,子类可以共享到这些扩展
LoopImages.prototype.getImageLength = function(){
return this.imagesArray.length;
}
// 扩展渐隐轮播类。对子类扩展,不影响同级的子类
FadeLoopImg.prototype.getContainer = function(){
return this.container;
}
事实上,从优化代码,我们还看出了原型模式的另一个好处:原型对象是一个可共享的对象,父类的实例对象和子类的实例对象都可以共享原型对象上的方法。当原型对象被扩展时,那么基于这个原型对象的父类及其子类都可以同步被扩展。
5、原型继承(对被继承的对象进行浅复制)
// 浅复制:封装一个实现原型继承的方法
function prototypeExtend(){
var F = function(){};
var args = arguments;
for(var i=0; i<args.length; 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('奔跑速度');
},
jump: function(){
console.log('跳跃动作');
}
});
penguin.swim();
penguin.run(10);
penguin.jump();
上述代码,使用 prototypeExtend() 方法创建对象,我们就无须再使用 new 关键字调用类的构造器来创建对象了。
完!!!
网友评论