Appearance
Day.js 架构分析
整体架构
Day.js 采用模块化设计,核心库只包含基本功能,通过插件系统扩展功能。
dayjs/
├── core/ # 核心功能
│ ├── index.js # 主入口
│ ├── dayjs.js # Day.js 类
│ ├── parse.js # 日期解析
│ ├── format.js # 日期格式化
│ └── utils.js # 工具函数
├── plugin/ # 插件系统
│ ├── index.js # 插件管理
│ └── *.js # 各个插件
└── locale/ # 国际化
├── en.js # 英语
├── zh-cn.js # 简体中文
└── *.js # 其他语言核心模块
1. Day.js 类
Day.js 类是核心类,封装了日期对象和操作方法。
javascript
class Dayjs {
constructor(config) {
this.$d = new Date(config);
this.$y = this.$d.getFullYear();
this.$M = this.$d.getMonth();
this.$D = this.$d.getDate();
this.$W = this.$d.getDay();
this.$H = this.$d.getHours();
this.$m = this.$d.getMinutes();
this.$s = this.$d.getSeconds();
this.$ms = this.$d.getMilliseconds();
}
}2. 日期解析
日期解析模块负责将各种格式的日期字符串解析为 Date 对象。
javascript
function parseDate(config) {
if (config === null || config === undefined) {
return new Date();
}
if (config instanceof Date) {
return config;
}
if (typeof config === 'string') {
return new Date(config);
}
if (typeof config === 'number') {
return new Date(config);
}
return new Date();
}3. 日期格式化
日期格式化模块负责将日期对象格式化为字符串。
javascript
function format(date, formatString) {
const tokens = {
YYYY: date.getFullYear(),
MM: padZero(date.getMonth() + 1),
DD: padZero(date.getDate()),
HH: padZero(date.getHours()),
mm: padZero(date.getMinutes()),
ss: padZero(date.getSeconds())
};
return formatString.replace(/YYYY|MM|DD|HH|mm|ss/g, (match) => {
return tokens[match];
});
}4. 日期操作
日期操作模块负责对日期进行加减操作。
javascript
function add(date, amount, unit) {
const result = new Date(date);
switch (unit) {
case 'year':
case 'years':
result.setFullYear(result.getFullYear() + amount);
break;
case 'month':
case 'months':
result.setMonth(result.getMonth() + amount);
break;
case 'day':
case 'days':
result.setDate(result.getDate() + amount);
break;
case 'hour':
case 'hours':
result.setHours(result.getHours() + amount);
break;
case 'minute':
case 'minutes':
result.setMinutes(result.getMinutes() + amount);
break;
case 'second':
case 'seconds':
result.setSeconds(result.getSeconds() + amount);
break;
}
return result;
}插件系统
插件架构
Day.js 采用插件架构,通过 extend 方法扩展功能。
javascript
const installedPlugins = [];
function extend(plugin, option) {
if (!plugin.$i) {
plugin(option, Dayjs, dayjs);
plugin.$i = true;
installedPlugins.push(plugin);
}
return dayjs;
}插件接口
插件需要实现特定的接口:
javascript
function plugin(option, Dayjs, dayjsClass) {
// 扩展 Dayjs 类
Dayjs.prototype.methodName = function() {
// 实现逻辑
};
// 扩展 dayjs 函数
dayjsClass.staticMethod = function() {
// 实现逻辑
};
}工具模块
1. 工具函数
Day.js 提供各种工具函数:
- padZero:补零
- isLeapYear:判断闰年
- getDaysInMonth:获取月份天数
- compareDates:比较日期
2. 辅助模块
Day.js 提供辅助功能:
- 国际化:支持多语言
- 插件系统:支持扩展功能
- 链式调用:支持链式调用
数据流
处理流程
输入日期
↓
解析日期
↓
创建 Day.js 对象
↓
应用操作
↓
格式化输出
↓
输出结果配置选项
基本选项
- locale:设置语言
- strict:严格解析模式
- format:默认格式
高级选项
- plugins:加载插件
- customParseFormat:自定义格式解析
- timezone:时区设置
错误处理
错误类型
Day.js 可能抛出的错误:
- 解析错误:日期格式不正确
- 格式化错误:格式字符串不正确
- 操作错误:日期操作失败
错误处理策略
Day.js 采用宽松的错误处理策略,对于无效输入返回当前日期。
性能优化
1. 缓存机制
缓存解析和格式化结果,提高性能。
2. 惰性计算
惰性计算日期属性,减少不必要的计算。
3. 插件按需加载
插件按需加载,减少初始加载时间。
可扩展性
1. 插件系统
通过插件系统扩展功能,保持核心库轻量。
2. 自定义格式
支持自定义日期格式。
3. 自定义语言
支持自定义语言包。
总结
Day.js 采用模块化设计,核心库轻量,通过插件系统扩展功能。它提供了与 Moment.js 相似的 API,但体积更小,性能更好。通过本节的学习,你将理解 Day.js 的架构设计,为后续的源代码学习和核心功能实现打下基础。
