在js中做数字字符串补0

通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的比较简单的处理方法是这样:

function formatDate(d) {
  var D=['00','01','02','03','04','05','06','07','08','09']
  with (d || new Date) return [
    [getFullYear(), D[getMonth()+1]||getMonth()+1, D[getDate()]||getDate()].join('-'),
    [D[getHours()]||getHours(), D[getMinutes()]||getMinutes(), D[getSeconds()]||getSeconds()].join(':')
  ].join(' ');
}


这种方法是逻辑比较简单的,而且规则也简单。除了with(d||new Date)的使用之外,也算不上什么技巧。但是,如果用这种方法来做数字字符串补0,那么结果显然不妙。51js的月影提供了另一个方案:

function pad(num, n) {
  return Array(n>num?(n-(''+num).length+1):0).join(0)+num;
}

调用示例如下:

pad(100, 4);  // 输出:0100

月影在这里分析了其中的技巧,以及代码长短与效率上的平衡:

http://hi.baidu.com/akira_cn/blog/item/90ba2a8b07c867dafc1f1045.html

 

最后月影推荐的是“质朴长存法”:

/* 质朴长存法  by lifesinger */
function pad(num, n) {
    var len = num.toString().length;
    while(len < n) {
        num = "0" + num;
        len++;
    }
    return num;
}


这个在“没事就射鸟”同学的博客里做了分析:

http://lifesinger.org/blog/2009/08/the-harm-of-tricky-code/

 

月影同学有一件事是没有做的,就是没说明“为什么那个短代码的效率更低?”。

答案是“表面看来,用array.join来替代循环是高效的,但忘掉了一个数组创建的开销”。对此有没有法子呢?我有过另一个解决的思路。如下:

/* 查表法(不完善)  by aimingoo */
pad = function(tbl) {
  return function(num, n) {
    return (((tbl[n = n-num.toString().length]) || (tbl[n] = Array(n).join(0))) + num);
  }
}([]);


这个路子跟前面的formatDate()是一样的,只不是formatDate()里的表是一个确定的数组,而这里的数组则是动态生成,然后缓存在tbl[]里面。这个缓存的tbl[]数组是使用一个函数调用参数的形式,保持在最终的pad()函数的上层闭包里面。为了让上面的这个过程清晰一点,我重排代码格式如下:

pad = function(tbl) {
  return function(num, n) {
    return (
      ((tbl[n = n-num.toString().length]) ||
       (tbl[n] = Array(n).join(0))) +
      num
    );
  }
}([]);


好的。到这里,先别急,还有两个问题要解决。其一,当不需要补0时,上述的tbl[0]返回空值,所以会进入到“||”运算的第二个分支,因此导致Array()重算一次,也就是说“不补0的情况效率其实最低”。其二,当num长度大于n时,也就变成了“补负数个零”。“补负数个零”显然不行,一般对此处理成“不需要补零”,于是又回到了第一个问题。

 

这两个问题可以一次解决,其实就是多一次判断:

/* 查表法(完善版本)  by aimingoo */
pad = function(tbl) {
  return function(num, n) {
    return (0 >= (n = n-num.toString().length)) ? num : (tbl[n] || (tbl[n] = Array(n+1).join(0))) + num;
  }
}([]);


当然,也可以象前面一样整理一下这个代码格式。或者,采用一个完全不用“(函数式语言的)连续运算等技巧”的版本:

/* 查表法(过程式版本)  by aimingoo */
pad = function() {
  var tbl = [];
  return function(num, n) {
    var len = n-num.toString().length;
    if (len <= 0) return num;
    if (!tbl[len]) tbl[len] = (new Array(len+1)).join('0');
    return tbl[len] + num;
  }
}();


算法永远都是如此,要不是时间换空间,要不就是空间换时间。射雕同学的“质朴长存法”是时间换空间的方法,而这里的查表法则是空间换时间的方案。这个函数会在tbl中持续一个字符串数组,如果num是非常经常变化的,那么效率也不会有太大提升——对于过于频繁变化的系统,缓存就意义不大了。其实逻辑都差不多,月影同学只是少走了一步而已。

 

<think>嗯,用户想知道在JavaScript中如何给字符串前面零。这个需求挺常见的,比如格式化日期或者数字的时候,比如把“3”变成“03”。那首先我得回想一下JavaScript中有哪些字符串处理的方法。 首先想到的是padStart()方法。这个方法可以在字符串前面填充指定的字符,直到达到指定的长度。比如str.padStart(targetLength, padString),如果原字符串长度不够,就用padString来填充前面。这应该是最直接的方法了。例如,'5'.padStart(2, '0')会得到'05'。不过要注意兼容性,因为padStart是ES6引入的,旧浏览器可能不支持,但现在的环境大多都支持了。 另外,用户可能不知道这个方法,或者需要兼容旧环境,这时候可能需要自己写一个函数。比如,可以先计算需要多少个0,然后用循环或者字符串拼接来实现。例如,定义一个函数,参数是数字和长度,然后生成相应数量的0,再和原字符串拼接。不过这种方法效率可能不高,特别是当需要0很多的时候。 还有一种方法是用slice()函数。比如,先构造一个足够长的0字符串,然后拼接原字符串,再用slice截取需要的长度。例如,('0000' + num).slice(-4)会把num换成前面0的四位字符串。这种方法比较巧妙,但需要预先知道最大长度,或者构造足够长的0字符串,可能不够灵活。 然后要考虑用户的具体情况,比如输入是数字还是字符串,是否需要处理负数,或者非数字的情况。比如,如果输入的是数字,可能需要先换成字符串,再进行处理。例如,var num = 5; num.toString().padStart(2, '0')。 还要注意,padStart的第二个参数默认是空格,所以如果只传长度,的是空格,必须明确指定填充字符为'0'。此外,如果原字符串长度已经大于等于目标长度,padStart不会任何处理,直接返回原字符串,这也是需要注意的。 可能用户的需求是固定位数,比如总是显示两位数字,这时候用padStart(2, '0')就足够了。如果位数不固定,比如有时需要到3位,有时4位,就需要根据具体情况调整参数。 另外,用户可能关心性能问题,比如哪种方法效率更高。padStart是原生方法,通常比自定义的循环或字符串拼接更高效,尤其是在处理大量数据的时候。所以推荐优先使用padStart。 总结一下,解决方案主要有两种:使用padStart方法,或者自定义函数。根据用户的浏览器支持情况来选择。如果用户的环境支持ES6,那么padStart是最佳选择。否则,可以用slice或者循环的方法来零。</think>在JavaScript中实现字符串零操作主要有以下两种常用方法: ### 方法一:padStart()方法(推荐) ES6新增的`padStart()`方法专门用于字符串位: ```javascript let num = '5'; let paddedNum = num.padStart(2, '0'); // '05' console.log(paddedNum); ``` - 第一个参数是目标长度(如需要两位数则填2) - 第二个参数是填充字符(默认空格) - 原字符串长度超过目标长度时直接返回原值 - 支持链式调用:`num.toString().padStart(3,'0')` ### 方法二:slice()配合字符串拼接 传统方法使用字符串截取实现: ```javascript function padZero(num, length) { return ('0'.repeat(length) + num).slice(-length); } console.log(padZero(9, 3)); // '009' ``` - 通过`'0'.repeat(length)`生成足够长的0字符串 - 使用`slice(-length)`截取尾部指定长度 - 支持数字类型自动换 ### 对比说明 | 方法 | 优点 | 注意事项 | |-----------|-----------------------|------------------------| | padStart() | 原生方法,语法简洁 | 需要ES6支持(IE不支持)[^1] | | slice() | 兼容性好,支持所有浏览器 | 需要处理数字换和长度计算 | ### 扩展应用 ```javascript // 日期格式化示例 const formatDate = d => [d.getDate(), d.getMonth()+1] .map(v => v.toString().padStart(2, '0')) .join('/'); // 输出'03/05' ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值