【JS】经常使用设想形式

JS经常运用设想形式

大型单页运用里,庞杂度上升到肯定水平时,没有恰当的设想形式举行降耦,后续的开辟也难以动手。
而设想形式恰是为了降耦而存在。

单例形式

单例形式的中心是确保只要一个实例,而且供应全局接见。

特性

满足“单一职责准绳” : 运用代办形式,不在组织函数中推断是不是已建立过该单例;

满足惰性准绳

运用

弹出上岸窗口。

实例

 var getSingle = function (fn) {
    var res;
    return function() {
        return res || (res = fn.apply(this, arguments));
    }
}

var createPopup() {
    var div = document.createElement('div');
    div.innerHTML = "Login window";
    div.style.display = "none"; 
    document.body.appendChild(div);
    return div;
}

var createLoginPopup = getSingle(createPopup);            
//create popup div here by using a given function, 满足两个准绳 

document.getElementById("loginBt").onclick = function() {
    var popup = createLoginPopup();
    pop.style.display = "block";
}

组织函数形式

/**
 * 组织一个动物的函数 
 */
function Animal(name, color){
    this.name = name;
    this.color = color;
    this.getName = function(){
        return this.name;
    }
}
// 实例一个对象
var cat = new Animal('猫', '白色');
console.log( cat.getName() );

原型形式

function Person(){  
}

Person.prototype.name = "bill";
Person.prototype.address = "GuangZhou";
Person.sayName = function (){
    alert(this.name);  
}

var person1 = new Person();
var person2 = new Person();
 
//测试代码
alert(person1.name);   // bill
alert(person2.name);    // bill
person1.sayName();    //bill
person2.sayName();    //bill

person1.name = "666";

alert(person1.name);   // 666
alert(person2.name);    // bill
person1.sayName();    //666
person2.sayName();    //bill

夹杂形式

/**
 * 夹杂形式 = 原型形式 + 组织函数形式
 */
function Animal(name, color){
    this.name = name;
    this.color = color;

    console.log( this.name  +  this.color)
}
Animal.prototype.getInfo = function(){
    console.log('称号:'+ this.name);
}

function largeCat(name, color){
    Animal.call(null, name, color);

    this.color = color;
}

largeCat.prototype = create(Animal.prototype);
function create (parentObj){
    function F(){}
    F.prototype = parentObj;
    return new F();
};

largeCat.prototype.getColor = function(){
    return this.color;
}
var cat = new largeCat("Persian", "白色");
console.log( cat )

工场形式

工场:函数内部发生b对象并返回。

1. 
function a(name){
  var b = new object();
    b.name = name;
    b.say = function(){
        alert(this.name);
    }   
       return b    
}
2. 
function Animal(opts){
    var obj = new Object();
    obj.name = opts.name;
    obj.color = opts.color;
    obj.getInfo = function(){
        return '称号:'+obj.name +', 色彩:'+ obj.color;
    }
    return obj;
}
var cat = Animal({name: '波斯猫', color: '白色'});
cat.getInfo();

简朴工场形式

简朴工场形式的理念就是建立对象,对差别类的实例化;只须要建立一个对象,然后经由历程对这个对象大批的要领和属性,并在终究将对象返回出来

//basketball base class  
var Baseketball = function(){  
  this.intro = 'baseketball is hotting at unitedstates';  
}  
Baseketball.prototype = {  
  getMember : function(){\  
    console.log('each team needs five players');  
  },  
  getBallSize : function(){  
    console.log('basketball is big');  
  }  
}  
//football base class   
var Football = function(){  
  this.intro = 'football is popular at all of the world';  
}  
Football = function(){  
  getMember = function(){  
  
  },  
  getBallSize = function(){  
  
  }  
}  
//sport factory  
var SportsFactory = function(name){  
  switch(name){  
    case 'NBA':  
      return new Baseketball();  
    case 'wordCup':  
      return new Football();  
  }  
}  
  
//when you want football   
var football = SportsFactory('wordCup');  
console.log(football);  
console.log(football.intro);  
football.getMember(); 

迭代器形式

装潢者形式

战略形式

定义一个个能够互相替代的算法,而且把他们封装起来。

特性

  1. 相符开放-关闭准绳 : 要修正运用的算法时没必要深切函数内部举行修正,只需修正战略类;
  2. 将算法的完成与运用分脱离,进步算法复用性;
  3. 经由历程组合、托付和多态防止多重前提挑选语句;

运用

动画完成差别的缓动效果。

平常分为两个部份:战略类于环境类。战略类用于封装种种算法,而且担任详细的盘算历程; 环境类担任吸收用户的要求,而且把要求托付给某一个战略类。由于各个战略类完成的算法和盘算的效果差别,而环境类挪用战略类的要领倒是雷同的,这就表现了多态性。要想完成差别的算法,只须要替代环境类中的战略类即可。

在js中,我们没必要组织战略类,可直接运用函数作为战略对象。

示例

var strategies = {
    "s1": function() {
        //algo 1
    },
    "s2": function() {
        //algo 2
    }, 
    "s3": function() {
        //algo 3
    }
 }
 
 var someContext =  new SomeConext();
 someContext.start("s1");  //using s1 to calculate
 //someContext.add("s1");  or add s1 as a rule for validation

表面形式

也可译为门面形式。它为子体系中的一组接口供应一个一致的界面, Facade形式定义了一个高层接口,这个接口使得这一子体系越发轻易运用。引入表面角色以后,运用者只须要直接与表面角色交互,运用者与子体系之间的庞杂关系由表面角色来完成,从而降低了体系的耦合度。
比方在家要看影戏,须要翻开声响,再翻开投影仪,再翻开播放器等等,引入表面角色以后,只须要挪用“翻开影戏装备”要领就能够。表面角色封装了翻开投影仪等操纵,给运用者供应更轻易运用的要领。

作用

  1. 简化庞杂接口
  2. 解耦和,屏障运用者对子体系的直接接见

实例

在形式上,表面形式在javascript中就像如许:

function a(x){
   // do something
}
function b(y){
   // do something
}
function ab( x, y ){
    a(x);
    b(y);
}

下面的一个例子,把阻挠冒泡和阻挠默许事宜放到了表面角色中:

var N = window.N || {};

N.tools = {
    stopPropagation : function( e ){
        if( e.stopPropagation ){
            e.stopPropagation();
        }else{
            e.cancelBubble = true;
        }
    },

    preventDefault : function( e ){
        if( e.preventDefault ){
            e.preventDefault();
        }else{
            e.returnValue = false;
        }
    },
    
    stopEvent : function( e ){
        N.tools.stopPropagation( e );
        N.tools.preventDefault( e );
    }

表面形式在javascript的运用重要能够分为两类,某块代码重复涌现,比方函数a的挪用基础都涌如今函数b的挪用之前,那末能够斟酌斟酌将这块代码运用表面角色包装一下来优化结构。另有一种就是关于一些浏览器不兼容的API,安排在表面内部举行推断,处置惩罚这些题目最好的体式格局就是将跨浏览器差别悉数集合安排到一个表面形式实例中来供应一个对外接口。

代办形式

代办形式的定义:为其他对象供应一种代办以掌握对这个对象的接见。在某些情况下,一个对象不适合或许不能直接援用另一个对象,而代办对象能够在客户端和目的对象之间起到中介的作用。

假造代办

假造代办是把一些开支很大的对象,延晚到真正须要它的时刻才去建立实行

图片懒加载

//图片加载
let imageEle = (function(){
    let node = document.createElement('img');
    document.body.appendChild(node);
    return {
        setSrc:function(src){
            node.src = src;
        }
    }
})();

//代办对象
let proxy = (function(){
    let img = new Image();
    img.onload = function(){
        imageEle.setSrc(this.src);
    };
    return {
        setSrc:function(src){
            img.src = src;
            imageEle.setSrc('loading.gif');
        }
    }
})();

proxy.setSrc('example.png');

兼并http要求

假如有一个功用须要频仍举行要求操纵,如许开支比较大,能够经由历程一个代办函数网络一段时间内要求数据,一次性发出



//上传要求
let upload = function(ids){
    $.ajax({
        data: {
            id:ids
        }
    })
}

//代办兼并要求
let proxy = (function(){
    let cache = [],
        timer = null;
    return function(id){
        cache[cache.length] = id;
        if(timer) return false;
        timer = setTimeout(function(){
            upload(cache.join(','));
            clearTimeout(timer);
            timer = null;
            cache = [];
        },2000);
    }    
})();
// 绑定点击事宜
let checkbox = document.getElementsByTagName( "input" );
for(var i= 0, c; c = checkbox[i++];){
    c.onclick = function(){
        if(this.checked === true){
            proxy(this.id);
        }
    }
}

缓存代办

缓存代办能够作为一些开支大的运算效果供应临时的存储,下次运算时,假如通报进来的参数跟之前一致,则能够直接返回前面存储的运算效果

//盘算乘积
let mult = function(){
    let result = 1;
    for(let i = 0,len = arguments.length;i < len;i++){
        result*= arguments[i];
    }
    return result;
}

//缓存代办
let proxy = (function(){
    let cache = {};
    reutrn function(){
        let args = Array.prototype.join.call(arguments,',');
        if(args in cache){
            return cache[args];
        }
        return cache[args] = mult.apply(this,arguments);
    }
})();

优瑕玷

1.长处:代办形式能将代办对象与被挪用对象星散,降低了体系的耦合度。代办形式在客户端和目的对象之间起到一个中介作用,如许能够起到庇护目的对象的作用。代办对象也能够对目的对象挪用之前举行其他操纵。
2.瑕玷:增加了体系的庞杂度

观察者形式

模块形式

/**
 * 模块形式 = 封装大部份代码,只暴露必须接口
 */
var Car = (function(){
    var name = '法拉利';
    function sayName(){
        console.log( name );
    }
    function getColor(name){
        console.log( name );
    }
    return {
        name: sayName,
        color: getColor
    }
})();
Car.name();
Car.color('赤色');
    原文作者:梵鹿
    原文地址: https://segmentfault.com/a/1190000013297339
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞