美文网首页
原型模式

原型模式

作者: helloyoucan | 来源:发表于2019-04-30 20:07 被阅读0次

    原型模式:用原型实例指向创建对象的类,使用于创建新的对象的类共享原型对象的属性以及方法

    需求1:创建轮播图

    // 图片轮播类
    const LoopImages = function(imgArr,container){
        this.imagesArray = imgArr //轮播图片数组
        this.container = container  //轮播图片容器
        this.createImage = function(){} //创建轮播图
        this.changeImage = function(){} //切换下一张图片
    }
    

    需求2:轮播图可能会有不同的切换方式:上下切换、左右切换、渐隐切换
    优化1:抽象出一个基类,让不同切换方式的类去基础基类,对于差异性的需求通过重写继承下来的属性或者方法

    //上下滑动切换类
    const SlideLoopImg = function(imgArr,container){
        //构造函数继承图片轮播类
        LoopImages.call(this.imgArr,container)
        //重写继承的切换图片方法
        this.changeImage = function(){
            console.log('SlideLoopImg changeImage function')
        }
    }
    
    //渐隐切换类
    const FadeLoopImg = function(imgArr,container,arrow){
        LoopImages.call(this,imgArr,container)
        //切换箭头私有变量
        this.arrow = arrow
        this.changeImage = function(){
            console.log('FadeLoopImg changeImage function')
        }
    }
    
    //实例化一个渐隐切换图片类
    const fadeImg = new FadeLoopImg(
            ['1.png','2.png','3.png'],
            'slide',
            ['left.png','right.png']
        )
    fadeImg.changeImage();
    

    问题:每次子类继承都要创建一个父类,若父类构造函数有耗时较长的逻辑,每次初始化都要坐一些重复性的东西,性能消耗很大
    优化2:简单有差异的属性放在构造函数中,消耗资源较多的方法放在基类的原型中

    //图片轮播类
    const LoopImages = function(imgArr,container){
        this.imagesArray = imgArr //轮播图片数组
        this.container = container  //轮播图片容器
    }
    LoopImages.prototype = {
        createImage(){
            //创建轮播图
        },
        changeImage(){
            //切换下一张图片
        }
    }
    
    //上下滑动切换类
    const SlideLoopImg = function(imgArr,container){
        //构造函数继承图片轮播类
        LoopImages.call(this.imgArr,container)
        
        
    }
    SlideLoopImg.prototype = new LoopImages()
    //重写继承的切换图片方法
    SlideLoopImg.prototype.changeImage = function(){
            console.log('SlideLoopImg changeImage function')
        }
    
    //渐隐切换类
    const FadeLoopImg = function(imgArr,container,arrow){
        LoopImages.call(this,imgArr,container)
        //切换箭头私有变量
        this.arrow = arrow
        
    }
    FadeLoopImg.prototype = new LoopImages()
    FadeLoopImg.prototype.changeImage = function(){
        console.log('FadeLoopImg changeImage function')
    }
    
    
    //实例化一个渐隐切换图片类
    const fadeImg = new FadeLoopImg(
            ['1.png','2.png','3.png'],
            'slide',
            ['left.png','right.png']
        )
    fadeImg.changeImage();
    

    问题:基类的构造函数比较复杂、消耗性能时,多个子类的重复继承多次,消耗性能、耗时也会多次
    优化3:不要通过new关键字去复制基类,而是通过对这些对象属性或者方法进行复制来实现创建

    /*
    * 基于已经存在的模板对象克隆出新对象的模式
    * 参数为模板对象
    * 注意:这里对模板引用类型的属性进行了浅复制(引用类型属性共享),当根据需求可以自行深复制(引用类型属性复制)
    */
    function prototypeExtend(...args){
        const F = function(){} //缓存类,为实例化返回对象临时创建
        for(let i = 0,l=args.length;i<l,i++){
            // 遍历每个模板对象中的属性
            for(const o in args[i]){
                // 将这些属性复制到缓存类原型
                F.prototype[j] = args[i][j]
            }
        }
        // 返回类的一个实例
        return new F()
    }
    
    //例子
    //企鹅游戏创建企鹅对象,没有且基类,只提供了一些动作模板对象
    const penguin = prototypeExtend(
        { speed:20,swim(){console.log('游泳速度 '+this.speed)} },
        { run(speed){console.log('奔跑速度 '+ speed)} },
        { jump(){console.log('跳跃动作')} }
    )
    penguin.swim() //游泳速度 20
    penguin.run(10) //奔跑速度 10
    penguin.jump() // 跳跃动作
    

    相关文章

      网友评论

          本文标题:原型模式

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