所见即所得,所见即所碍
系列概述:
- 阅读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与任何数组 或 值 连接在一起
注意:
- 产生一个新的数组(⚠️这一定程度上导致了较push性能不是很好)
- 浅拷贝
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)