lodash源码分析(map和reject函数)

map函数分析

我的实现

function map(array, fn) {
    let result = [];
    if (!(array && array.length)) {
        return result
    }

    for(let i=0; i< array.length; i++) {
        if (fn(array[i], i, array)) {
            result.push(i)  
        }
    }

    return result
}

别人的实现

function map(array, iteratee) {
  let index = -1
  const length = array == null ? 0 : array.length
  const result = new Array(length)

  while (++index < length) {
    result[index] = iteratee(array[index], index, array)
  }
  return result
}

区别

1.好像唯一的区别是,lodash中是先将固定长度的数据定义好,然后去修改每个数组的值;但是我的实现是每次都push;是不是后者效率更高呢?

_.reject 函数

我的实现

function isFunction(functionToCheck) {
    return {}.toString().call(functionToCheck) == '[object Function]'
}

function reject(jsonObject, match) {

    if (!jsonObject || !match ) {
        return jsonObject
    }

    if (isFunction(match)) {
        throw new TypeError('Expected a function')
    }

    
    if (Array.isArray(jsonObject)) {
        let result = [];
        for (let i=0; i < jsonObject.length; i++) {
                if (match(jsonObject[i])) {
                    result = [...result,jsonObject[i]]
                }
            }

        return result
    } else {
        let result = [];
        for (let key in jsonObject) {
                if (match(jsonObject[key])) {
                    result.push(jsonObject[key]);
                }
            }

        return result
    }
    
}

别人的实现

function negate(predicate) {
  if (typeof predicate != 'function') {
    throw new TypeError('Expected a function')
  }
  return function(...args) {
    return !predicate.apply(this, args)
  }
}

function filter(array, predicate) {
  let index = -1
  let resIndex = 0
  const length = array == null ? 0 : array.length
  const result = []

  while (++index < length) {
    const value = array[index]
    if (predicate(value, index, array)) {
      result[resIndex++] = value
    }
  }
  return result
}

function filterObject(object, predicate) {
  object = Object(object)
  const result = []

  Object.keys(object).forEach((key) => {
    const value = object[key]
    if (predicate(value, key, object)) {
      result.push(value)
    }
  })
  return result
}

function reject(collection, predicate) {
  const func = Array.isArray(collection) ? filter : filterObject
  return func(collection, negate(predicate))
}

export default reject

差别有两个:
1.对predicate函数进行了二次封装(调用时使用apply方式,这个部分的确是我没有考虑清楚)
2.将两个filter函数拆分出去,代码结构的确比我好
3.loop object类型时,使用的是object.keys来进行循环。查了一下资料,for..in会将prototype chain上都循环出去,但是Object.keys不会。

_pick方法(实现差距有点大,还没看懂)

参考链接:
https://segmentfault.com/a/1190000008738183

你可能感兴趣的:(lodash源码分析(map和reject函数))