美文网首页
JavaScript设计模式 | 07-原型模式

JavaScript设计模式 | 07-原型模式

作者: 夏海峰 | 来源:发表于2018-08-20 14:00 被阅读6次

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 关键字调用类的构造器来创建对象了。


完!!!

相关文章

网友评论

      本文标题:JavaScript设计模式 | 07-原型模式

      本文链接:https://www.haomeiwen.com/subject/iaxliftx.html