我們對 JavaScript 擴充功能其中一個較常的做法便是對 Date.prototype 的擴充。因為我們知道,Date 類別只提供了若干取得日期元素的方法,如 getDate(),getMinute()…卻沒有一個轉換為特定字串的格式化方法。故所以,利用這些細微的方法,加以封裝,組合我們想要的日期字串形式。一般來說,這個格式化函數可以定義在 Date 物件的原型身上,也可以獨立一個方法寫出。定義原型方法的操作如 Date.prototype.format = function(date){……},使用時候直接 new Date().format(YYYY:MM:DD) 即可,彷彿就是 Date 物件的原生方法。但定義原型方法卻略嫌有「入侵」 JS 原型的不足。設計 API 之時必須考慮這個問題。我的建議是,使用者按照自己的判斷去做決定,只是呼叫的方式不同,不影響過程的邏輯即可。
下面的一個例子就是以獨立函數寫出的 JavaScript 日期格式化函數,獨立的 format 函數。回到格式化的這項知識點上,我們考查的是怎麼實現的、運用了哪些原理。傳統字串拼接如 indexOf() substr() 雖然能夠實現,但明顯不僅效率低下,而且程式碼冗長,還是適宜引入正則表達式的方法,先寫出字串正則然後再進行結果的命中匹配。我們先來看看來自 Steven Levithan 的範例:
另外,程式碼中的 ("00" o[k]).substr(String(o[k]).length) 也是有趣的地方,前面加上兩個什麼意思呢?原來目的是為了取數組的最後兩位。這是綜合利用 substr() 方法的一個技巧,substr 第一個參數是開始截取的 index,若不指定第二個參數 index 則保留字串到最後(str.length)。於是,我們事先加多了多少位,原本固定的字串長度不變(String(o[k].length))的情況下,那麼就留下多少個位。 (p.s 「00」相當於佔位符,亦可用其他字串「XX」代替無差別)
仍然覺得這段程式碼有不少的困難?我們嘗試把月影的函數重寫為可讀性較強的程式碼,原理上趨於一致可是沒那麼多的技巧,相信這樣可以節省大家的時間,回頭再去看月影的程式碼也不遲。
}
return format;
for (key in o) { // 如果沒有指定參數,子字串將延續到 stringvar 的最後。
if (new RegExp("(" key ")").test(format)) {
> value = $1.length == 1 ? value : ("00" value).substr(value.length),
format = format.replace($1, value);
}
return format ;
}