经验分享 - 提高生产效率的一些编码技巧(1)

发布于 2023-10-29 00:55:32 字数 12020 浏览 42 评论 0

本文包含了一些个人开发经验总结和设计模式的总结,希望能给大家有所帮助。

条件语句 if 使用技巧

将代码少的逻辑放到 if 中,而更多的逻辑当成正常系处理,更有利于阅读和理解。

方法

原始代码:

if(condition){
    //中间有 100 行代码
}else{
    //这里只有 1 行代码!
};

以上逻辑最好的书写规范是:

if(!condition){
    //1 行代码!
    return;
};

//剩余 100 行代码

案例

原始代码:

selectCategory : function(categoryId, isRedirect) {
    if (categoryId) {
        $('#userPersonasTagDrop .input-group').hide();
        $('#tagSubCategory').addClass('subcategory-not-all').show();
        
        walleUtilStorage.setItem(this.storageLocalCategoryId, categoryId);
        walleUtilStorage.setItem(this.storageLocalTagId, '');
        
        isRedirect      // 比如从收藏夹跳转过来
            ? $('#tagSubCategory span:first').text(this.model.queryParam.tagName)
            : $('#tagSubCategory span:first').text('请选择标签');
        isRedirect || this._getPersonasTagList(categoryId, '', true);
        
    } else {
        $('#userPersonasTagDrop .input-group').show();
        $('#tagSubCategory').hide();
        $('#collectBtn').attr('disabled');
        $('.item-group-search').attr('disabled');
    }
}

优化后:

selectCategory : function(categoryId, isRedirect) {
    //优化 1
    if (!categoryId) {
        $('#userPersonasTagDrop .input-group').show();
        $('#tagSubCategory').hide();
        $('#collectBtn').attr('disabled');
        $('.item-group-search').attr('disabled');
        return;
    };
    
    $('#userPersonasTagDrop .input-group').hide();
    $('#tagSubCategory').addClass('subcategory-not-all').show();
    
    walleUtilStorage.setItem(this.storageLocalCategoryId, categoryId);
    walleUtilStorage.setItem(this.storageLocalTagId, '');
    
    //优化 2
    if(!isRedirect){
        $('#tagSubCategory span:first').text('请选择标签');
        return;
    };
    
    $('#tagSubCategory span:first').text(this.model.queryParam.tagName)
    this._getPersonasTagList(categoryId, '', true);
}

参考

代码大全,第 15 章

重复语句 for 循环化(表驱动法)

代码中发现有太多重复的语句,看似相同,但是又有些不同,于是乎就本能的习惯使用 if 语句写一大片!

其实最好的做法是代码去重!

核心的思想: 就是想尽一切办法将相似的部分放到一个对象或者数组中,然后循环处理。

示例 1

显示一年内各个月的天数。

最 low 的写法:

function getDaysByMonth(month){
    var days = 0;    
    if(month == 1){
        days = 31;
    }else if(month == 2){
        days = 28; // 不用考虑闰年的情况
    }else if(month == 3){
        days = 31;
    }else if(...){
        ...
    };
    return days;
};

采用表驱动法的思路

function getDaysByMonth(month){
    //创建一张表
    var daysAry = [31,28,31,30,31,30,31,31,30,31,30,31];
    return daysAry[month];
};

示例 2

原始代码:

if (currentIdx === model.TAB_SYSTEM) { model.searchKeyWd.systemKeyWd = $searchInput.val(); }
if (currentIdx === model.TAB_MODULE) { model.searchKeyWd.moduleKeyWd = $searchInput.val(); }
if (currentIdx === model.TAB_AUTH) { model.searchKeyWd.authKeyWd = $searchInput.val(); }

优化:

var mapper = [{
    key : model.TAB_SYSTEM,
    model : model.searchKeyWd.systemKeyWd
},{
    key : model.TAB_MODULE,
    model : model.searchKeyWd.moduleKeyWd
},{
    key : model.TAB_AUTH,
    model : model.searchKeyWd.authKeyWd
}];

for(var i=0,size=mapper.length;i<size;i++){
    var obj = mapper[i];
    if(currentIdx === obj.key){
        obj.model = $searchInput.val();
    };
};

示例 3

原始代码:

function fun1(){
    confirmTodoObj.todo === todoType.SYSTEM_UPDATE && result && result();
    confirmTodoObj.todo === todoType.MODULE_UPDATE && result && result();
    confirmTodoObj.todo === todoType.AUTH_UPDATE   && result && result();
    confirmTodoObj.todo === todoType.SYSTEM_ADD    && result && result();
    confirmTodoObj.todo === todoType.MODULE_ADD    && result && result();
    confirmTodoObj.todo === todoType.AUTH_ADD      && result && result();
}

优化 1:

function fun1(){
    if(!result){
        return;
    };
    
    if(confirmTodoObj.todo === todoType.SYSTEM_UPDATE
        || confirmTodoObj.todo === todoType.MODULE_UPDATE
        || confirmTodoObj.todo === todoType.AUTH_UPDATE
        || confirmTodoObj.todo === todoType.SYSTEM_ADD
        || confirmTodoObj.todo === todoType.MODULE_ADD
        || confirmTodoObj.todo === todoType.AUTH_ADD){
    
        result();
    };
}

优化 2:

function fun1(){
    if(!result){
    return;
};

switch(confirmTodoObj.todo){
    case todoType.SYSTEM_UPDATE:
    case todoType.AUTH_UPDATE:
    case todoType.SYSTEM_ADD:
    case todoType.MODULE_ADD:
    case todoType.AUTH_ADD:
        result();
        break;
};

最终优化:

function fun1(){
    if(!result){
        return;
    };
    
    var checkKeyList = [
        'SYSTEM_UPDATE',
        'AUTH_UPDATE',
        'SYSTEM_ADD',
        'MODULE_ADD',
        'AUTH_ADD'
    ];
    
    for(var i=0,size=checkKeyList.length; i<size; i++){
        if(confirmTodoObj.todo === todoType[checkKeyList[i]]){
            result();
        };
    };
}

参考

代码大全,第 18 章

巧用 Array.joinString.split 函数

  • Array.join - 将所有 数组 或者 类数组 的元素拼接为一个字符串并返回这个字符串,默认的连接符为 ,
  • String.split - 将一个字符串通过特定的字符串分割为一个数组并返回这个数组,如果不指定分隔符则默认返回一个字符,里面只有一个元素就是当前字符串;

示例

//join 的用法

var elements = ['Fire', 'Wind', 'Rain'];

console.log(elements.join()); //expected output: Fire,Wind,Rain
console.log(elements.join('-')); //expected output: Fire-Wind-Rain
//split 用法
var elements = 'Jan,Feb,Mar,Apr';

console.log(elements.split());//["Jan,Feb,Mar,Apr"]
console.log(elements.split(','));//["Jan","Feb","Mar","Apr"]
console.log(elements.split(''));//["J", "a", "n", ",", "F", "e", "b", ",", "M", "a", "r", ",", "A", "p", "r"]

案例一

假如后台需要传一个字段,该字段是所有页面上选中的元素的 id,通过逗号拼接,如: 102,235,356,213

最 low 的做法

//通过代码将所有元素放到一个数组中
var idAry = [102,235,356,213];

//循环拼接数组
var result = '';
for(var i=0;i<idAry.length;i++){
    result += idAry[i] + ',';
};

//发现最后多了一个逗号,去掉!
result = result.substring(0,result.length-1);

推荐的办法

//通过代码将所有元素放到一个数组中
var idAry = [102,235,356,213];
var result = idAry.join();

案例二

页面需要循环一个数组,动态拼接为 html 语句 <option> 最后填充到页面上的 <select> 中。

最 low 的做法

var objAry = [{
    id : 1,
    name : '张三'
},{
    id : 2,
    name : '李四'
}];

var html = '';
for(var i=0;i<objAry.length;i++){
    result += '<option>'+ objAry[i].name +'</option>';
};

$('select').html(html);

推荐的办法

var objAry = [{
    id : 1,
    name : '张三'
},{
    id : 2,
    name : '李四'
}];

var html = $.map(objAry,function(d){
    return '<option>'+ d.name +'</option>';
}).join('');

$('select').html(html);

什么是类数组 Array-Like?

jQuery 避免手动拼接 URL 参数

get 请求时,很多人习惯手动拼接 url 参数,比如:

var queryParam = 'val1='+val1+'&val2='+val2+'&val3='+val3;
var getUrl = url + '?' + queryParam;

推荐使用 jQuery$.param() 方法,或者其它库提供的类似方法。

var queryParam = {
    val1 : val1,
    val2 : val2,
    val3 : val3
};

var getUrl = url + '?' + $.param(queryParam);

详细说明: http://api.jquery.com/jquery.param

jQuery 对象复制或合并

假如有对象 a 和 对象 b ,要实现如下功能:

  1. a 的属性复制到 b 对象上;
  2. ab 合并成新对象 c ;

推荐使用 jQuery$.extend() 方法,或者其它库提供的类似方法。

ab 对象分别如下:

var a = {
    apple: 0,
    banana: { 
        weight: 52, 
        price: 100 
    },
    cherry: 97
};

var b = {
    banana: {
        price: 200
    },
    durian: 100
};

目标 1:将 a 的属性复制到 b 对象上:

//通过递归的方式,将 a 对象的所有属性复制到 b 对象上
$.extend(true, b, a);

//如果不使用递归,而是浅拷贝,则:
$.extend(b, a);

目标 2:将 ab 合并成新对象 c ;

//通过递归的方式,将 a 对象的所有属性复制到 b 对象上
var c = $.extend(true, {}, b, a);

//如果不使用递归,而是浅拷贝,则:
var c = $.extend({}, b, a);

详细说明: http://api.jquery.com/jquery.extend

思考:如果自己实现以上方式,该怎么写?PS:需要考虑深拷贝和浅拷贝的问题;写出来可以与 jQuery 源码对比下。

三元表达式(Conditional (ternary) Operator)

三元表达式规则:

condition ? expr1 : expr2 

使用三元表达式能简化代码结构,能少写一组 if/else

示例

var str = ture ? 'yes' : 'no';

OR 短路操作符 Short-Circuits

短路操作符规则:

//If exp1 is true then exp2
exp1 || exp2
var a = b || 1;

翻译过来如下:

if(b){
    a = b;
}else{
    a = 1;
};

只所以可以这么写,原因是 js 是一门弱类型语言,每个变量默认都默认继承一个 true 或者 false 值,称之为:truthy 或者 falsy!

参考: https://www.sitepoint.com/javascript-truthy-falsy/

&& 条件判断

与短路操作类似,还有一种写法如下:

var a = b && 1;

翻译过来如下:

if(b) {
    a = 1;
}else{
    a = b;
};

更多 JS 中的一些常用的快速写法

获取时间戳

//传统写法
var timestamp = new Date().getTime(); //1512113674165

//快速写法
var timestamp = +new Date(); //1512113674165

浮点数取整

//传统写法
var var1 = parseInt(11.6); //11

//快速写法
var var1 = ~~11.6; //11

//不常用,但是可以
var var1 = 11.6 | 0; //11

位操作符 ~https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
位操作符 |https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
~~ 解惑: http://rocha.la/JavaScript-bitwise-operators-in-practice

科学计数法

//传统写法
for(var i=0;i<10000;i++){};

//快速写法
for(var i=0;i<1e4;i++){};

获取随机码

Math.random().toString(16).substring(2); //13 位,如:7c4a0278b4509
Math.random().toString(36).substring(2); //11 位,如:5b1chmfvhmo

合并两个数组

var a = [1,2,3];
var b = [4,5,6];
Array.prototype.push.apply(a, b);
console.log(a); //[1,2,3,4,5,6]

不增加变量交换两个值

a= [b, b=a][0];

获取数组的最大和最小值

Math.max.apply(Math, [1,2,3]) //3
Math.min.apply(Math, [1,2,3]) //1

推荐书籍

虽然这本书的示例代码都是 VB 写的,但是思想非常实用,建议大家都看下。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

不忘初心

暂无简介

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文