美文网首页
lodash源码分析(map和reject函数)

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

作者: shuta | 来源:发表于2018-06-27 11:20 被阅读0次

    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函数)

          本文链接:https://www.haomeiwen.com/subject/rxymyftx.html