目录:
一、介绍
二、个人手写
1、个人未看源码思路
2、个人手写代码
三、源码分析
1、源码思路
四、总结
字数:大约900字
一、介绍
名称:array-first
地址:https://github.com/jonschlinkert/array-first.git
示例:
var first = require('array-first');
first(['a', 'b', 'c', 'd', 'e', 'f']);
//=> 'a'
first(['a', 'b', 'c', 'd', 'e', 'f'], 1);
//=> 'a'
first(['a', 'b', 'c', 'd', 'e', 'f'], 3);
//=> ['a', 'b', 'c']
可能很多人一看就知道怎么实现,但是看源码、手写源码,都应该循序渐进,先从简单的开始,写多了之后,遇到复杂的也有思路、有逻辑、有规范的去实现。
二、个人手写
都是没有看源码前的手写。对比之后才能学到更多,更深刻。同样的,如果是我们自己手写,你应该怎样写,看起来好像很简单。
1、个人未看源码思路
1、判断是否是数组、判断是否有第二个参数
2、如果没有第二个参数,默认返回数组第一个数据。第二个参数为1也一样。
3、如果有第二个参数,判断大小,如果大于1,则返回截取原数据长度为第二个参数的新数组。因为是返回数组的前面数据,所以就不考虑第二个参数为负数的时候啦。
按照这个思路,我们实现的代码是这样的:
2、个人手写代码
const first = (list: string[], size?: number) => {
// 不是数组则提示
if(!Array.isArray(list)) throw new Error("list is not a Array!");
// 如果为空数组,提示需要至少有一个
if(!list?.length) throw new Error("list length must larger than 0!");
// 没有第二个参数或者第二个参数为1。返回数组第一个
if(!size || size === 1) return list[0];
// 如果第二个参数小于数组长度则截取
if(size < list.length) return list.splice(0, size)
// 如果第二个参数大于等于数组长度则直接返回数组
return list;
}
测试
first(['a', 'b', 'c', 'd', 'e', 'f']);
//=> 'a'
first(['a', 'b', 'c', 'd', 'e', 'f'], 1);
//=> 'a'
first(['a', 'b', 'c', 'd', 'e', 'f'], 3);
//=> ['a', 'b', 'c']
first(['a', 'b', 'c', 'd', 'e', 'f'], 8);
//=> ['a', 'b', 'c', 'd', 'e', 'f']
这样,我们的代码就写出来了。
三、源码分析
那我们就要看看人家写的源码。
function arrayFirst(arr, num) {
if (!Array.isArray(arr)) {
throw new Error('array-first expects an array as the first argument.');
}
if (arr.length === 0) {
return null;
}
var first = slice(arr, 0, isNumber(num) ? +num : 1);
if (+num === 1 || num == null) {
return first[0];
}
return first;
};
function isNumber(num) {
if (typeof num === 'number') {
return num - num === 0;
}
if (typeof num === 'string' && num.trim() !== '') {
return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
}
return false;
};
1、源码思路
同样:
首先判断是否是数组
再判断数组长度
然后他用了js数组的slice方法。并且调用了isNumber方法。之前文章说过,finite检查一个数值是否为有限的,即不是Infinity。如果参数类型不是数值,Number.isFinite一律返回false。所以知道,它如果传的第二个参数不是数字,统一视为1。否则slice第二个参数为正的number。他是不管怎样都去截取数组,个人认为不合理。如果大于了数组长度再去截取,不就是浪费性能啦。
当然它对第二个参数的判断更充分,我这里只是用了ts限制了。如果不用ts,就会有问题。
还有就是以后都尽可能用ts来写啦。让大家习惯看ts。也会慢慢成长的。不熟悉的可以看看往期ts的教程。
四、总结
1、写功能模块时,可以引用好的第三方依赖,当然主要逻辑尽可能用自己的,不然就失去了自己写的意义了,那就叫般啦