源码阅读系列二、array-first
1、概述
array-first
核心只有15行,主要的功能是获取数组的第一个元素或前n个元素。npm仓库https://www.npmjs.com/package/array-first
使用到的模块详解:
kind-of 获取值的本机类型。
is-number 如果值为有限数,则返回true。
array-slice 数组切片法。从开始索引到结束索引(但不包括)切片数组。
is-Buffer 此模块允许您在不使用Buffer.isBuffer(包括browserify中的整个缓冲区模块)的情况下检查对象是否为缓冲区。
模块引用实例图:
2、源码解析
阅读package.json
文件可知,本模块使用了array-slice
、is-number
模块
var isNumber = require('is-number');
var slice = require('array-slice');
// arr必须为数组
// num可不传,不传默认为1
module.exports = function arrayFirst(arr, num) {
// 如果arr不是数组,则抛出错误
if (!Array.isArray(arr)) throw new Error('array-first expects an array as the first argument.');
// 如果arr是数组,但是长度为0,返回null
if (arr.length === 0) return null;
// 调用array-slice库。返回截取结果
// 调用is-number库。返回true、false
// +num语法,把num强制转换为数字
var first = slice(arr, 0, isNumber(num) ? +num : 1);
// 如果第二个参数为空或1,返回第一个
if (+num === 1 || num == null) {
return first[0];
}
return first;
};
node
中使用array-first
库:
var first = require('array-first');
console.log(first([])); // null
console.log(first('aaaa')); // array-first expects an array as the first argument.
console.log(first(['a', 'b', 'c', 'd'])); // a
console.log(first(['a', 'b', 'c', 'd'], 1)); // a
console.log(first(['a', 'b', 'c', 'd'], 3)); // [ 'a', 'b', 'c' ]
3、引用模块亮点
array-first
模块中,+num
语法,把num强制转换为数字。kind-of
模块中,采用了大量的判断来区分不同类型。主要使用typeof
、instanceof
、toString.call(val)
方法来鉴定类型。array-slice
模块中,没有使用数组slice
方法,而是使用最普通的while
循环数组添加;arr.length >>> 0
移位操作符的使用超乎我的想象,后来查了查,才知道,>>>
是无符号右移,>>
是有符号移位;移位操作符在移位前做了两种转换,第一将不是number类型的数据转换为number,第二将number转换为无符号的32bit数据,也就是Uint32类型。这些与移位的位数无关,移位0位主要就是用了js的内部特性做了前两种转换。x >>> 0
本质上就是保证x有意义(为数字类型),且为正整数,在有效的数组范围内(0 ~ 0xFFFFFFFF),且在无意义的情况下缺省值为0。感兴趣可以阅读https://blog.csdn.net/weixin_34252686/article/details/88860424
。
4、总结
在开发中,获取数组第一个元素或前n个元素,我们大都直接只用slice
方法,但是array-first
,考虑到的东西很多,如:是否为数组啊、数组长度啊…引用的其他库,代码我也都简单阅读了一下,不是很难,但是亮点地方很多+num
、arr.length >>> 0
语法,这些都超出了我的知识面,正好也是给了自己一个查缺补漏的机会。大家如果有机会可以阅读一下kind-of
、is-number
、array-slice
、is-buffer
这四个库的代码。
|
|
内容持续更新中…
但行好事,莫问前程。
lvan学习笔记-文章内容仅个人观点
2021.10.27