# 标记

const LARGE_ARRAY_SIZE = 200
function baseDifference(array, values, iteratee, comparator) {
  let includes = arrayIncludes
  let isCommon = true
  const result = []
  const valuesLength = values.length

  if (!array.length) {
    return result
  }
  if (iteratee) {
    values = map(values, (value) => iteratee(value))
  }
  if (comparator) {
    includes = arrayIncludesWith
    isCommon = false
  }
  else if (values.length >= LARGE_ARRAY_SIZE) {
    includes = cacheHas
    isCommon = false
    values = new SetCache(values)
  }
  outer:
  for (let value of array) {
    const computed = iteratee == null ? value : iteratee(value);

    value = (comparator || value !== 0) ? value : 0;
    if (isCommon && computed === computed) {
      let valuesIndex = valuesLength;
      while (valuesIndex--) {
        if (values[valuesIndex] === computed) {
          continue outer;
        }
      }
      result.push(value);
    }
    else if (!includes(values, computed, comparator)) {
      result.push(value);
    }
  }
  return result;
}

这段代码,设计比较精妙。

  • 通过标记,可以引用指定语句,例如这里的continue outer;,不过实际适用场景比较少。
  • includes在各个情况下,引用的方法都不一样,并且活用了实参形参不一致的特征,简化了代码量。
  • 通过isCommon来区分复杂与普通处理模式。
  • value = (comparator || value !== 0) ? value : 0;
    • 这一段代码比较奇怪,在没有提供comparator的情况下,如果value === 0,则将value赋值为0。
    • value === 0有三种情况+00-0。但是因为上面代码会在比较时使用set,而set无法区分+0-0
最近更新时间: 2020/9/6 11:30:38