年末一直在抽空学习 Chrome 扩展
开发以及 Dart
、 Flutter
的移动端开发,两个多月没有更新文章。在这里顺便把 2021
的学习计划更新下。
春节期间已经实现了一个自定义配置的多引擎搜索扩展 Rummage
,下一篇分享下扩展的设计、开发和发布,再进一步学习计划如下:
- 学习
TypeScript
,抽空开发一个配色应用,名字还没想好,应用应该内置大量经典配色盘,还可以将任意图片量化为一组配色并保存,而且用TypeScript
实现Chrome 扩展
和用Flutter
实现移动端APP
两个平台。 源码阅读计划
:继续完成lodash
的源码分析,学习Vue3
和ElementUI
的源码实现。地铁读书计划
:早晚地铁读《学习 Javascript 数据结构与算法》、《Javascript 设计模式与开发实践》、《Flutter 实战》和重读《Javascript 高级程序设计 3》工具学习计划
:Webpack
和Git
的深入学习。
接上篇 —— dayjs 源码解析(三):插件(中) —— 继续解析 dayjs
的源码。
剩余的插件功能比较零散,实现起来也比较简单,所以解析的代码不全部放在文章里了,简单介绍下剩余每个插件的功能:
advancedFormat
:实现更复杂的格式化;arraySupport
:实现对数组结构参数的支持;badMutable
:由不可变对象转变成可变对象;buddhistEra
:实现东南亚佛历的格式化;calendar
:实现日历;dayOfYear
:返回一个number
来表示日期是年中第几天,或设置成是年中第几天;devHelper
:开发时插件,显示一些提示和警告方便开发。;localData
和localizedFormat
:实现本地化(这一块看的有点懵);minMax
:挑选最大值或最小值;pluralGetSet
:给每个单位添加复数形式方法,与非复数同名函数一致;toArray
和toObject
:返回时间数组或对象;updateLocale
:更新指定语言的任何属性,而其他属性将会保持不变 ;
具体的分析已经放在了 Github 中,感兴趣可以移步对应文件。本篇作为 dayjs
源码解析系列的最后一篇,来动手实现一个自己的插件。
目录如下:
- dayjs 源码解析(一):概念、locale、constant、utils
- dayjs 源码解析(二):Dayjs 类
- dayjs 源码解析(三):插件(上)
- dayjs 源码解析(四):插件(中)
- dayjs 源码解析(五):插件(下)
手写一个 Dayjs 插件
作为一个示范插件,应该尽量实现简单。咱们就来动手写一个按照指定范围随机取一个时刻的方法。
插件设计
- 实现静态方法
randBetween
,必传参数为2
个时刻,返回2
个时刻间的1
个随机时刻。 - 实现类实例的原型方法
randBetween
, 必传参数为1
个时刻,返回该时刻与实例时刻间的1
个随机时刻。 - 入参的时刻类型可以为
Dayjs
实例、Date
实例或13
位时间戳,返回的时刻类型为Dayjs
实例。
实现
实现的思路如下:
- 两个时刻统一封装为
Dayjs
实例 - 取到两个时刻的
13
位时间戳。(valueOf
) - 计算两个时间戳内的随机整数
- 将随机事件封装为
Dayjs
实例返回
工具函数:计算随机整数
按照计算机科学的惯例,应当使用前闭后开。
/**
* @description: 计算随机整数
* @param {Number} min 最大值
* @param {Number} max 最小值
* @return {Number} 前闭后开
*/
const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;
工具函数:求随机时刻
dayjs().valueOf()
方法可以直接取到 13
位的时间戳。
/**
* @description: 计算随机时刻
* @param {Dayjs| Date | Number} ref1 两端时刻
* @param {Dayjs| Date | Number} ref2 两端时刻
* @return {Dayjs} 返回一个Dayjs实例
*/
const between = (ref1, ref2) => {
let val1 = dayjs(ref1).valueOf();
let val2 = dayjs(ref2).valueOf();
let randomResult = random(...[val1, val2].sort((a, b) => a - b));
return dayjs(randomResult);
};
挂载到 dayjs 函数对象和类实例原型上
最后一步,就是将方法挂载到需要的地方。挂载到原型上时需要注意不可以用箭头函数,因为需要 this
指向实例。
/**
* @description: plugin
* @param {Object} option option
* @param {Class} Dayjs Dayjs类
* @param {Function} dayjs dayjs函数对象
*/
let dayjsRandom = (option, Dayjs, dayjs) => {
const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;
const between = (ref1, ref2) => {
let val1 = dayjs(ref1).valueOf();
let val2 = dayjs(ref2).valueOf();
let randomResult = random(...[val1, val2].sort((a, b) => a - b));
return dayjs(randomResult);
};
Dayjs.prototype.randBetween = function (ref) {
return between(this, ref);
};
dayjs.randBetween = (ref1, ref2) => between(ref1, ref2);
};
测试
2021年1月1日0时0分0秒
的 13
位时间戳为 1609430400000
。
// 挂载插件
dayjs.extend(dayjsRandom);
// 实例测试
dayjs().randomBetween(new Date(1609430400000)).format(); // output: 2021-01-27T06:53:42+08:00
dayjs().randomBetween(dayjs(1609430400000)).format(); // output: 2021-02-04T02:56:27+08:00
dayjs().randomBetween(1609430400000).format(); // output: 2021-01-22T02:38:09+08:00
// 函数对象测试
dayjs.randomBetween(new Date(), 1609430400000).format(); // output: 2021-01-04T01:30:56+08:00
三种格式的输出都没有问题。
总结
dayjs
源码解析系列完成 ?。该系列先解析了关于时间的一些概念,又分解了 dayjs
项目的结构并分析了 Dayjs类
的源码,再解析了各个插件的源码,最后手动实现了一个插件。
前端记事本,不定期更新,欢迎关注!
- 微信公众号: 林景宜的记事本
- 博客:林景宜的记事本
- 掘金专栏:林景宜的记事本
- 知乎专栏: 林景宜的记事本
- Github: MageeLin
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!