在js中做數(shù)字字符串補0(js補零)
通常遇到的一個問題是日期的“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(' ');
}
這種方法是邏輯比較簡單的,而且規(guī)則也簡單。除了with(d||new Date)的使用之外,也算不上什么技巧。但是,如果用這種方法來做數(shù)字字符串補0,那么結(jié)果顯然不妙。51js的月影提供了另一個方案:
function pad(num, n) {
return Array(n>num?(n-(''+num).length+1):0).join(0)+num;
}
調(diào)用示例如下:
pad(100, 4); // 輸出:0100
月影在這里分析了其中的技巧,以及代碼長短與效率上的平衡:
最后月影推薦的是“質(zhì)樸長存法”:
/* 質(zhì)樸長存法 by lifesinger */
function pad(num, n) {
var len = num.toString().length;
while(len < n) {
num = "0" + num;
len++;
}
return num;
}
這個在“沒事就射鳥”同學(xué)的博客里做了分析
月影同學(xué)有一件事是沒有做的,就是沒說明“為什么那個短代碼的效率更低?”。
答案是“表面看來,用array.join來替代循環(huán)是高效的,但忘掉了一個數(shù)組創(chuàng)建的開銷”。對此有沒有法子呢?我有過另一個解決的思路。如下:
/* 查表法(不完善) 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()里的表是一個確定的數(shù)組,而這里的數(shù)組則是動態(tài)生成,然后緩存在tbl[]里面。這個緩存的tbl[]數(shù)組是使用一個函數(shù)調(diào)用參數(shù)的形式,保持在最終的pad()函數(shù)的上層閉包里面。為了讓上面的這個過程清晰一點,我重排代碼格式如下:
pad = function(tbl) {
return function(num, n) {
return (
((tbl[n = n-num.toString().length]) ||
(tbl[n] = Array(n).join(0))) +
num
);
}
}([]);
好的。到這里,先別急,還有兩個問題要解決。其一,當(dāng)不需要補0時,上述的tbl[0]返回空值,所以會進入到“||”運算的第二個分支,因此導(dǎo)致Array()重算一次,也就是說“不補0的情況效率其實最低”。其二,當(dāng)num長度大于n時,也就變成了“補負數(shù)個零”。“補負數(shù)個零”顯然不行,一般對此處理成“不需要補零”,于是又回到了第一個問題。
這兩個問題可以一次解決,其實就是多一次判斷:
/* 查表法(完善版本) 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;
}
}([]);
當(dāng)然,也可以象前面一樣整理一下這個代碼格式。或者,采用一個完全不用“(函數(shù)式語言的)連續(xù)運算等技巧”的版本:
/* 查表法(過程式版本) 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;
}
}();
算法永遠都是如此,要不是時間換空間,要不就是空間換時間。射雕同學(xué)的“質(zhì)樸長存法”是時間換空間的方法,而這里的查表法則是空間換時間的方案。這個函數(shù)會在tbl中持續(xù)一個字符串?dāng)?shù)組,如果num是非常經(jīng)常變化的,那么效率也不會有太大提升——對于過于頻繁變化的系統(tǒng),緩存就意義不大了。其實邏輯都差不多,月影同學(xué)只是少走了一步而已。
相關(guān)文章
理解Javascript_01_理解內(nèi)存分配原理分析
在正式開始之前,我想先說兩句,理解javascript系列博文是通過帶領(lǐng)大家分析javascript執(zhí)行時的內(nèi)存分配情況,來解釋javascript原理,具體會涵蓋javascript預(yù)加載,閉包原理,面象對象,執(zhí)行模型,對象模型...,文章的視角很特別,也非常深入,希望大家能接受這種形式,并提供寶貴意見。2010-10-10
Js setInterval與setTimeout(定時執(zhí)行與循環(huán)執(zhí)行)的代碼(可以傳入?yún)?shù))
最近在做項目時用到了定時執(zhí)行的js方法,setInterval與setTimeout時間長了不用有些生疏了,所以自己總結(jié)了一下,記下來,以便以后使用。2010-06-06
JavaScript實現(xiàn)點擊出現(xiàn)子菜單效果
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)點擊出現(xiàn)子菜單,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-02-02
extjs 04_grid 單擊事件新發(fā)現(xiàn)
EXTJS GRID 中單擊行和單元格獲得行或者單元格的內(nèi)容(數(shù)據(jù)),本文將整理此功能的應(yīng)用,需要了解的朋友可以參考下2012-11-11
微信小程序?qū)崿F(xiàn)的日期午別醫(yī)生排班表功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的日期午別醫(yī)生排班表功能,結(jié)合實例形式分析了微信小程序?qū)崿F(xiàn)基于日期時間、針對上午、下午、凌晨、夜間等時段的排班功能相關(guān)操作技巧,需要的朋友可以參考下2019-01-01

