我们对 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 的例子:
[url=http://www.w3schools.com/jsref/jsref_parse.asp] * Date object's <a href="http://www.w3schools.com/jsref/jsref_parse.asp" mce_href="http://www.w3schools.com/jsref/jsref_parse.asp">parse()</a> method)
* @param {String} format (可选的)任意的日期格式化字符串。(默认为'm/d/Y')(optional) Any valid date format string (defaults to 'm/d/Y')
* @return {String} 已格式化字符串。The formatted date string
*/
date: function(v, format) {
if (!v) {
return "";
}
if (!Ext.isDate(v)) {
v = new Date(Date.parse(v));
}
return v.dateFormat(format || Ext.util.Format.defaultDateFormat);
}
date 构造器还可以通过算出距离1970起为多久的毫秒数来确定日期?——的确,这样也行,——也就说,举一反三,从这个问题说明,js 日期最小的单位是毫秒。
最终版本:
/**
* 日期格式化。详见博客文章:http://blog.csdn.net/zhangxin09/archive/2011/01/01/6111294.aspx
* e.g: new Date().format("yyyy-MM-dd hh:mm:ss")
* @param {String} format
* @return {String}
*/
Date.prototype.format = function (format) {
var $1, o = {
"M+": this.getMonth() + 1, // 月份,从0开始算
"d+": this.getDate(), // 日期
"h+": this.getHours(), // 小时
"m+": this.getMinutes(), // 分钟
"s+": this.getSeconds(), // 秒钟
// 季度 quarter
"q+": Math.floor((this.getMonth() + 3) / 3),
"S": this.getMilliseconds() // 千秒
};
var key, value;
if (/(y+)/.test(format)) {
$1 = RegExp.$1,
format = format.replace($1, String(this.getFullYear()).substr(4 - $1));
}
for (key in o) { // 如果没有指定该参数,则子字符串将延续到 stringvar 的最后。
if (new RegExp("(" + key + ")").test(format)) {
$1 = RegExp.$1,
value = String(o[key]),
value = $1.length == 1 ? value : ("00" + value).substr(value.length),
format = format.replace($1, value);
}
}
return format;
}