在js中做数字字符串补0(js补零)


Posted in Javascript onMarch 25, 2017

通常遇到的一个问题是日期的“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

月影在这里分析了其中的技巧,以及代码长短与效率上的平衡:
最后月影推荐的是“质朴长存法”:

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

这个在“没事就射鸟”同学的博客里做了分析
月影同学有一件事是没有做的,就是没说明“为什么那个短代码的效率更低?”。
答案是“表面看来,用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是非常经常变化的,那么效率也不会有太大提升——对于过于频繁变化的系统,缓存就意义不大了。其实逻辑都差不多,月影同学只是少走了一步而已。

Javascript 相关文章推荐
js 图片缩放(按比例)控制代码
May 27 Javascript
javascript 获取所有id中包含某关键字的控件的实现代码
Nov 25 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
Apr 11 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
Sep 24 Javascript
Javascript中typeof 用法小结
May 12 Javascript
在JS中操作时间之getUTCMilliseconds()方法的使用
Jun 10 Javascript
JS实现密码框根据焦点的获取与失去控制文字的消失与显示效果
Nov 26 Javascript
解析Node.js异常处理中domain模块的使用方法
Feb 16 Javascript
angular2系列之路由转场动画的示例代码
Nov 09 Javascript
详解无限滚动插件vue-infinite-scroll源码解析
May 12 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
Apr 25 Javascript
vue中destroyed方法的使用说明
Jul 21 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
Mar 25 #Javascript
JS去掉字符串前后空格或去掉所有空格的用法
Mar 25 #Javascript
javascript作用域链与执行环境详解
Mar 25 #Javascript
vue中用动态组件实现选项卡切换效果
Mar 25 #Javascript
使用vue.js写一个tab选项卡效果
Mar 25 #Javascript
JavaScript 实现 Tab 点击切换实例代码
Mar 25 #Javascript
JS操作xml对象转换为Json对象示例
Mar 25 #Javascript
You might like
IStream与TStream之间的相互转换
2008/08/01 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
Yii2-GridView 中让关联字段带搜索和排序功能示例
2017/01/21 PHP
PHP 进度条函数的简单实例
2017/09/19 PHP
PHP双向链表定义与用法示例
2018/01/31 PHP
PHP连接SQL Server的方法分析【基于thinkPHP5.1框架】
2019/05/06 PHP
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
javascript中的this详解
2014/12/08 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
2016/06/07 Javascript
快速解决js中window.location.href不工作的问题
2016/11/02 Javascript
前端自动化开发之Node.js的环境搭建教程
2017/04/01 Javascript
微信小程序 数据遍历的实现
2017/04/05 Javascript
jQuery异步提交表单实例
2017/05/30 jQuery
详解动画插件wow.js的使用方法
2017/09/13 Javascript
对angular 实时更新模板视图的方法$apply详解
2018/10/09 Javascript
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
Vue-cli3简单使用(图文步骤)
2019/04/30 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
2020/08/03 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
[02:16]2018年度CS GO最具人气选手-完美盛典
2018/12/16 DOTA
python实现JAVA源代码从ANSI到UTF-8的批量转换方法
2015/08/10 Python
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
简单谈谈python的反射机制
2016/06/28 Python
利用python提取wav文件的mfcc方法
2019/01/09 Python
Python3 串口接收与发送16进制数据包的实例
2019/06/12 Python
python函数定义和调用过程详解
2020/02/09 Python
Python random库使用方法及异常处理方案
2020/03/02 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
国际知名设计师时装商店:Coggles
2016/09/05 全球购物
献爱心大型公益活动策划方案
2014/09/15 职场文书
股东出资证明书(正规版)
2014/09/24 职场文书
优秀党员申报材料
2014/12/18 职场文书
三八妇女节致辞
2015/07/31 职场文书
2016八一建军节慰问信
2015/11/30 职场文书