Giter Site home page Giter Site logo

lodash-source-code-analyse's People

Contributors

jchappytime avatar

Stargazers

 avatar

Watchers

 avatar  avatar

lodash-source-code-analyse's Issues

_.slice(array, [start=0], [end=array.length])

1. 作用及使用

裁剪数组array,从start位置开始到end结束,但不包括end本身的位置。也就是左闭右开的形式。
这个方法可以替代数组本身的Array.slice()方法来确保数组正确返回。
【参数】

  1. array: 要裁剪的数组
  2. start=0: 开始位置
  3. end=array.length: 结束位置

2. 示例

  1. start和end都传
    slice

  2. start和end都不传
    slice

  3. 只传start

slice-2

3. 源码分析

源码:
function slice(array, start, end) {
  let length = array == null ? 0 : array.length;
  if (!length) {
    return [];
  }
  start = start == null ? 0 : start;    // 边界值设定
  end = end === undefined ? length : end;   // 边界值设定

  if (start < 0) {
    start = -start > length ? 0 : length + start;
  }
  end = end > length ? length : end;
  if (end < 0) {
    end += length;
  }
  length = start > end ? 0 : (end - start) >>> 0;   
  // 这里的>>>表示向右移位,>>>0的意思是无符号移位,该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被 
 // 丢弃,左侧用0填充。因为符号位变成了0,所以结果总是非负的。
  start >>>= 0;

  let index = -1;
  const result = new Array(length);
  while (++index < length) {
    result[index] = array[index + start];
    // 当index + 1的值小于数组长度时,result数组的index位置的值被赋值为array的[index+start位置的值]
  }
  return result;
}

_.difference(array, [values])

1. 作用及使用

创建一个具有唯一array值的数组,每个值不包含在其它给定的数组中。简单来说就是,检查第一个数组中的每个值,是否存在于第二个数组中,如果不存在则保留,存在则移除。
该方法使用SameValueZero做相等比较,结果值的顺序是由第一个数组中的顺序确定。
【参数】

  1. array: 要检查的数组
  2. [values]:排除的值(非必传)

2. 示例

1
2

3. 源码分析

源码:
function difference(array, ...values) {
  return isArrayLikeObject(array)
    ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
    : []
}

这个函数中涉及到的isArrayLikeObject,baseDifference,baseFlatten分别如下:

  • isArrayLikeObject (类数组的判断)

【作用】这个函数是为了判断array是否为数组,保证数组长度小于最大值。

function isArrayLikeObject(value) {
  return (typeof value === 'object' && value !== null) && (value != null && typeof value !== 'function' && isLength(value.length));
}

function isLength(value) {
  return typeof value === 'number' &&
    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;    // MAX_SAFE_INTEGER=9007199254740991
}
  • baseDifference

这个方法才是我们要研究的关键所在。

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
}
  • baseFlatten
function baseFlatten(array, depth, predicate, isStrict, result) {
  predicate || (predicate = isFlattenable)
  result || (result = [])

  if (array == null) {
    return result
  }

  for (const value of array) {
    if (depth > 0 && predicate(value)) {
      if (depth > 1) {
        // Recursively flatten arrays (susceptible to call stack limits).
        baseFlatten(value, depth - 1, predicate, isStrict, result)
      } else {
        result.push(...value)
      }
    } else if (!isStrict) {
      result[result.length] = value
    }
  }
  return result
}

function isFlattenable(value) {
  return Array.isArray(value) || isArguments(value) ||
    !!(value && value[spreadableSymbol])
}
这里的isArguments()方法的代码就不再贴出来了。

_.chunk(array, [size=1])

1. 作用及使用

将数组array拆分成多个size长度的区块,并将这些区块组成一个新的数组。如果array无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。
【参数】

  1. array:需要处理的数组
  2. [size=1]每个数组区块的长度

2. 示例:

  1. 不传size值
    1

  2. 传size值为2时
    2

3. 源码分析:

function chunk(array, size=1) {
  size = Math.max(toInteger(size), 0);
  const length = array === null ? 0 : array.length;
  if (!length || size < 1) { // 临界值判断
    return [];
  }
  let index = 0;
  let resIndex = 0;
  const result = new Array(Math.ceil(length / size));  // 此处是用array的长度除以size大小,得到能划分出的每个区块的数组的长度
  
  while (index < length) {
    result[resIndex++] = this.slice(array, index, (index += size));
    // 当index小于数组长度时,result数组的resIndex+1位置的值,被赋值为slice()方法分割出来的数组
  }
  return result;
}

这里slice()方法的源码见: slice分析

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.