代码重构

提炼函数
避免出现超大函数,独立出来的函数有助于代码复用,独立出来的函数更容易被覆写,独立出来的函数如果拥有一个良好的命名,他本身就起到了注释的作用
//例如:

var getUserInfo=funcion(){
    ajax("http://***.com/userInfo",function(data){
        console.log('userId:'+data.userId);
        console.log('userName:'+data.userName);
    });
}

//改写:
var getUserInfo=funcion(){
    ajax("http://***.com/userInfo",printDetails(data));
}
function printDetails(data){
        console.log('userId:'+data.userId);
        console.log('userName:'+data.userName);
};

 

合并重复的条件片段

//一个页面跳转的伪代码

var page=function(currPage){
    if(currPage<0){
        currPage=0;
        jump(currPage);
    }else if(currPage>=totalPage){
        currPage=totalPage;
        jump(currPage);
    }else{
        jump(currPage);
    }
}

//改写
var page=function(currPage){
    if(currPage<0){
        currPage=0;
    }else if(currPage>=totalPage){
        currPage=totalPage;
    }
    jump(currPage);
}

 

把条件分支语句提炼成函数

var getPrice=function(price){
    var date=new Date();

    if(date.getMonth()>=6&&date.getMonth()<=9){
        return price*0.8;
    }

    return price;
};

//改写:
var isSummer=function(){
    var date=new Date();
    return date.getMonth()>=6&&date.getMonth()<=9;
};
var getPrice=function(price){

    if(isSummer()){
        return price*0.8;
    }
    return price;
};

 


合理使用循环
//一个创建XHR对象的代码,为了简化,只实现IE9以下

var createXHR=function(){
    var XHR;
    try{
        XHR=new ActiceXObject('MSXML2.XMLHttp.6.0');
    }catch(e){
        try{
            XHR=new ActiceXObject('MSXML2.XMLHttp.3.0');
        }catch(e){
            XHR=new ActiceXObject('MSXML2.XMLHttp');
        }        
    }
    return XHR;
}

//改写:
var createXHR=function(){
    var versions=['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp'];
    for(var i=0,version;version=versions[i++];){
        try{
            return new ActiceXObject(version);
        }catch(e){

        }
    }
}

提前让函数退出代替嵌套条件分支

//一段遵守“一个函数只有一个出口”的伪代码

var del=function(obj){
    var ret;
    if(!obj.isReadOnly{   //不为只读的才能被删除
        if(obj.isFolder){  //如果是文件夹
            ret = deletFolder(obj);
        }else if(obj.isFile){
            ret=deletFile(obj);  //如果是文件
        }
    }
    return ret;
}

var del=function(obj){

    if(!obj.isReadOnly{      //不为只读的才能被删除
        return;
    }
    if(obj.isFolder){        //如果是文件夹
        return deletFolder(obj);
    }
    if(obj.isFile){
        return deletFile(obj);  //如果是文件
    }
}

 

传递对象参数代替过长的参数列表
//例:

var setUserInfo=function(id,name,age,sex,qq,phone){
    console.log("id"+id);
    console.log("name"+name);
    console.log("age"+age);
    console.log("sex"+sex);
    console.log("qq"+qq);
    console.log("phone"+phone);
}
setUserInfo(1231,'nike',18,'male','35498797','13200400580');

//改写

var setUserInfo=function(data){
    console.log("id"+data.id);
    console.log("name"+data.name);
    console.log("age"+data.age);
    console.log("sex"+data.sex);
    console.log("qq"+data.qq);
    console.log("phone"+data.phone);
}


setUserInfo(
    {
        id:1231,
        name:'nike',
        age:18,
        sex:'male',
        qq:'35498797',
        phone:'13200400580'
    }
);

 

少使用三目运算符
三目运算符常被用来if-else,两者的性能是差不多的,在实际开发中,即使一段代码循环一百万次,使用三目运算符和使用if-else的时间开销是在同一级别上的,相比损失的代码可读性和可维护性,三目运算符节省的代码量也可以忽略不计,让JS文件加载更快的方法有很多,如压缩,缓存,使用CDN等。如果条件分支逻辑简单清晰,这无碍我们使用三目运算符:var global=typeof window!=="undefined"?window:this;但如果条件分支逻辑非常复杂,最好使用if-else,这样阅读更加容易,后期修改也更加容易例如:

if(!aup||!bup){
    return a===doc?-1:
        b=doc?1:
        aup?-1:
        bup?1:
        sortInput?
        (indexOf.call(sortInput,a)-indexOf.call(sortInput,b)):
        0;
}

合理使用链式调用

————方法调用结束后返回对象自身

var User=function(){
    this.name=null;
    this.id=null;
};
User.prototype.setId=function(id){
    this.id=id;
    return this;
}
User.prototype.setName=function(name){
    this.name=name;
    return this;
}
var user=new User();
user.setName("nike").setId("132");

//或者
//
var User={
    id:null,
    name:null,
    setName:function(name){
        this.name=name;
        return this;
    },
    setId=function(id){
        this.id=id;
        return this;
    }
}
User.setName("nike").setId("132");

使用链式调用的方式并不会造成太多阅读上的困难,也确实能省下一些字符串和中间变量,但节省下来的字符数量同样是微不足道的,链式调用带来的坏处就是在调试的时候非常不方便,如果我们知道一条链中有错误出现,必须得先把这条链拆开才能加上一些调试log或者增加断电。这样才能定位错误出现的地方。所以还是使用普通调用比较好

 

var user=new User();
user.setId("134");
user.setName("nike");

用return退出多重循环

var func=function(){
    var flag=false;

    for(var i=0;i<10;i++){
        for(var j=0;j<10;j++){
            if(i*j>30){
                flag=true;
                break;
            }
        }
    if(flag===true)break;
    }
}

var func=function(){
    var flag=false;

    for(var i=0;i<10;i++){
        for(var j=0;j<10;j++){
            if(i*j>30)return;
        }
    }
}

当然用return直接退出方法会带来一个问题,如果在循环之后还有一些将被执行的代码呢?如果我们提前退出了整个方法,这些代码就不会被执行

var func=function(){
    var flag=false;

    for(var i=0;i<10;i++){
        for(var j=0;j<10;j++){
            if(i*j>30)return;
        }
    }
    console.log(".....");
}

为了解决这个问题我们可以把循环后面的代码放到return 后面,如果代码较多,就应该把它们提炼成一个单独的函数:

var print=function(){
    console.log(".....");
}

var func=function(){
    var flag=false;

    for(var i=0;i<10;i++){
        for(var j=0;j<10;j++){
            if(i*j>30)return print();
        }
    }
}

 

posted @ 2016-06-23 22:15  秋虹连宇  阅读(153)  评论(0编辑  收藏  举报