所见即所得,所见即所碍

系列概述:

  • 阅读lodash源码,并做适当笔记
  • 手抄一份,学习其中实现的小技巧
  • 尽量比较出与原生方法的区别

1. 函数效果

测试代码

const _ = require('lodash')

const vec = [1,2,3,4,5];
const a = {
 a: 1
}
const vec2 = _.concat(vec,2,a);
console.log(vec); //[ 1, 2, 3, 4, 5 ]
console.log(vec2);  //[ 1, 2, 3, 4, 5, 2, { a: 1 } ]
a.a = 2;
console.log(vec2); //[ 1, 2, 3, 4, 5, 2, { a: 2 } ]

效果描述:

_.concat(array, [values])
创建一个新数组,将array与任何数组 或 值 连接在一起

注意:

  1. 产生一个新的数组(⚠️这一定程度上导致了较push性能不是很好)
  2. 浅拷贝

2. 手抄代码

导入功能代码:

列举

  • arrayPush
  • baseFlatten
  • copyArray
  • isArray

比较有趣的地方:

拷贝数组

fucntion copyArray(source, array) {
    let index = -1, length = source.length;
    //利用短路求值特性,实现守护功能
    array || (array = Array(length);
    while(++index < length) {
        array[index] = source[index];
    }
    return array;
}

数组扁平化 (细节待flatten再说)

function baseFlatten(array, depth, predicate, isStrict, result) {
    const index = -1, length = array.length;

    predicate || (predicate = isFlattenable);
    result || (result = []);

    while(++index < length) {
        let value = array[index];
        if(depth > 0 && predicate(value)) {
            if(depth > 1) {
                //递归啦递归啦
                baseFlatten(value, depth-1, predicate, isStrict, result);
            } else {
                arrPush(result, value);
            }
        } else if(!isStrict) {
            // 什么数据会触发这个呢? ⚠️待解决
            result[result.length] = value;
        }
    }
    return rsult;
}

主要代码

function concat() {
    let length = arguments.length;
    if(!length) {
        return [];
    }

    let args = Array(length - 1),
            array = argument[0],
            index = length;

    //细品,比平时少了个变量,但一切刚刚好,👍
    while (index--) {
        args[index - 1] = arguments[index];
    }

    return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));

}

3. 技巧总结

  • 短路求值
//例
predicate || (predicate = isFlattenable);
  • 赋值,从后向前
//例

while (index--) {
    args[index - 1] = arguments[index];
}

不过这种单纯赋值操作,更直观的还是用slice, splice来实现吧

//例
vec.slice(1);
vec.splice(1)