最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • dayjs源码解析(五):插件(下)

    正文概述 掘金(林景宜)   2021-02-24   546

    年末一直在抽空学习 Chrome 扩展开发以及 DartFlutter 的移动端开发,两个多月没有更新文章。在这里顺便把 2021 的学习计划更新下。

    春节期间已经实现了一个自定义配置的多引擎搜索扩展 Rummage,下一篇分享下扩展的设计、开发和发布,再进一步学习计划如下:

    • 学习 TypeScript,抽空开发一个配色应用,名字还没想好,应用应该内置大量经典配色盘,还可以将任意图片量化为一组配色并保存,而且用 TypeScript 实现 Chrome 扩展和用 Flutter 实现 移动端APP 两个平台。
    • 源码阅读计划:继续完成 lodash 的源码分析,学习 Vue3ElementUI 的源码实现。
    • 地铁读书计划:早晚地铁读《学习 Javascript 数据结构与算法》、《Javascript 设计模式与开发实践》、《Flutter 实战》和重读《Javascript 高级程序设计 3》
    • 工具学习计划WebpackGit 的深入学习。

    接上篇 —— dayjs 源码解析(三):插件(中) —— 继续解析 dayjs 的源码。

    剩余的插件功能比较零散,实现起来也比较简单,所以解析的代码不全部放在文章里了,简单介绍下剩余每个插件的功能:

    • advancedFormat :实现更复杂的格式化;
    • arraySupport :实现对数组结构参数的支持;
    • badMutable :由不可变对象转变成可变对象;
    • buddhistEra :实现东南亚佛历的格式化;
    • calendar :实现日历;
    • dayOfYear :返回一个 number 来表示日期是年中第几天,或设置成是年中第几天;
    • devHelper :开发时插件,显示一些提示和警告方便开发。;
    • localDatalocalizedFormat :实现本地化(这一块看的有点懵);
    • minMax :挑选最大值或最小值;
    • pluralGetSet :给每个单位添加复数形式方法,与非复数同名函数一致;
    • toArraytoObject :返回时间数组或对象;
    • updateLocale :更新指定语言的任何属性,而其他属性将会保持不变 ;

    具体的分析已经放在了 Github 中,感兴趣可以移步对应文件。本篇作为 dayjs 源码解析系列的最后一篇,来动手实现一个自己的插件。

    目录如下:

    1. dayjs 源码解析(一):概念、locale、constant、utils
    2. dayjs 源码解析(二):Dayjs 类
    3. dayjs 源码解析(三):插件(上)
    4. dayjs 源码解析(四):插件(中)
    5. dayjs 源码解析(五):插件(下)

    手写一个 Dayjs 插件

    作为一个示范插件,应该尽量实现简单。咱们就来动手写一个按照指定范围随机取一个时刻的方法。

    插件设计

    • 实现静态方法 randBetween,必传参数为 2 个时刻,返回 2 个时刻间的 1 个随机时刻。
    • 实现类实例的原型方法 randBetween, 必传参数为 1 个时刻,返回该时刻与实例时刻间的 1 个随机时刻。
    • 入参的时刻类型可以为 Dayjs 实例、Date 实例或 13 位时间戳,返回的时刻类型为 Dayjs 实例。

    实现

    实现的思路如下:

    1. 两个时刻统一封装为 Dayjs 实例
    2. 取到两个时刻的 13 位时间戳。(valueOf
    3. 计算两个时间戳内的随机整数
    4. 将随机事件封装为 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


    起源地下载网 » dayjs源码解析(五):插件(下)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元