提升系列:12.获取格式化时间区间-3-4

75 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8天,点击查看活动详情

上一次掘金的征文活动,准确来说,应该是去年的最后一次掘金官方的征文活动,我没有参加那一次征文活动。距离上一次征文,好像有两三个月了,感觉时间过得有点漫长了,都快要忘记掘金的征文活动了。

现在掘金推出了新的一年的征文活动-掘金日新计划 · 2 月更文挑战,又要开始新的一年,新的一轮的征文挑战了。

征文挑战已经开始了,而我即将要参与这次征文活动,参与挑战,挑战自己。

提升系列

提升系列,我主要是想写一些平时工作上面,自己会用到的一些好的技巧或者方法。当然,这些技巧和方法是针对我自己的。

除此之外,还可能会写一些解决难点的方法。比如,遇到了某个难点,要通过什么方法来解决它?

正如它的名字一样--提升,通过学习一些好的技巧、方法,或者解决一些难题、难点,来提升我们的能力。

出这个提升系列,一方面,是提升自己的开发能力;另一方面,也希望这个提升系列,可以帮助到部分人,提升他们的开发能力。

在这个系列里,我能想到的或者实现方法,不一定是最好的。欢迎大家一起来参与讨论,有好的想法也可以告诉我一下。

前言

在上一篇文章里,我们介绍了到momentjs源码里面的createAdder方法。我们分析了createAdder方法的一些逻辑,它会调用createDuration方法,创建一个时长对象。

接下来,我们就分析一下createDuration方法,看下该方法是怎么创建时长对象。

实现

我们在vscode里面搜索一下createAdder方法,找了一会,找到了createAdder方法的定义:

  function createAdder(direction, name) {
      ...
      dur = createDuration(val, period);
      addSubtract(this, dur, direction);
      return this;
    };
  }

这是在createAdder方法里,执行createDuration方法的地方。我们点击进入该方法

function createDuration(input, key) {
    var duration = input,
      match = null,
      sign,
      ret,
      diffRes;
​
    if (isDuration(input)) {
      duration = {
        ms: input._milliseconds,
        d: input._days,
        M: input._months,
      };
    } else if (isNumber(input)) {
      duration = {};
      if (key) {
        duration[key] = input;
      } else {
        duration.milliseconds = input;
      }
    } else if (!!(match = aspNetRegex.exec(input))) {
      sign = match[1] === "-" ? -1 : 1;
      duration = {
        y: 0,
        d: toInt(match[DATE]) * sign,
        h: toInt(match[HOUR]) * sign,
        m: toInt(match[MINUTE]) * sign,
        s: toInt(match[SECOND]) * sign,
        ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
      };
    } else if (!!(match = isoRegex.exec(input))) {
      sign = match[1] === "-" ? -1 : 1;
      duration = {
        y: parseIso(match[2], sign),
        M: parseIso(match[3], sign),
        w: parseIso(match[4], sign),
        d: parseIso(match[5], sign),
        h: parseIso(match[6], sign),
        m: parseIso(match[7], sign),
        s: parseIso(match[8], sign),
      };
    } else if (duration == null) {
      // checks for null or undefined
      duration = {};
    } else if (
      typeof duration === "object" &&
      ("from" in duration || "to" in duration)
    ) {
      diffRes = momentsDifference(
        createLocal(duration.from),
        createLocal(duration.to)
      );
​
      duration = {};
      duration.ms = diffRes.milliseconds;
      duration.M = diffRes.months;
    }
​
    ret = new Duration(duration);
​
    if (isDuration(input) && hasOwnProp(input, "_locale")) {
      ret._locale = input._locale;
    }
​
    return ret;
  }

该方法里面,先是执行了几个if的条件判断,先分析一下这几个条件判断

  • 执行isDuration方法,判断参数input是否是Duration的实例对象
  • 执行isNumber方法,判断input是否是数字类型
  • 判断input是否符合aspNetRegex正则表达式
  • 判断input是否符合isoRegex正则表达式
  • 判断duration是否为null
  • 判断duration是否是对象,并且有from和to属性

上面这些条件判断,如果满足对应的条件,则进入对应条件的逻辑里执行。其实主要就是根据不同的条件,进行一些初始化操作,把各种条件尽量处理的一致。因为传递参数的时候,我们可以传递不同的参数。这些不同的参数,要怎么实现相同的效果呢?

就是通过这些初始化的操作,把不同的参数类型,处理成一致,抹平它们的差异化。

createDuration方法的最后,针对_local属性,单独做了判断处理。方法的最后,是返回Duration的实例对象。

小结

本小节主要分析了createAdder方法里面使用到的createDuration方法,也是做了一些简单的分析。如果大家有疑问,也可以自己到源码里查看一下。欢迎沟通交流。

最后,放上自己比较喜欢的一句诗句:

千淘万漉虽辛苦,吹尽狂沙始到金 - 唐 刘禹锡《浪淘沙》