源码赏析·数组转换工具arrify

前言

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

这是源码共读的第33期,链接:【若川视野 x 源码共读】第33期 | arrify 转数组

背景

挑了个最简单的一期开始,其实并没用过arrify,借此机会了解一番。

在npm上查找arrify,戳这里,这个包的数据还是挺厉害。

实践

根据他的README来实操感受一下。

简单来说arrify是一个数组转换工具,可以传入任意值转换成数组。

源码

arrify代码仓库地址,戳这里

下载代码到本地

shell 复制代码
git clone git@github.com:sindresorhus/arrify.git

vscode打开项目arrify,通过GitLens插件可以了解到该项目是在9年前初始化的,最近一次更新是在2年前。

首先查看package.json, 整个库采用esm编写,还有依赖了哪些库,可执行的命令脚本只有一个test,那就安装依赖,来执行一下这个test指令。

其中开发依赖了三个库:

  1. xo: 一个默认值很高的 js/ts linter (ESLint包装器)
  2. ava: nodejs的测试运行器
  3. tsd: 为类型定义编写测试,是.test-d.ts扩展文件

安装依赖:

shell 复制代码
npm install

执行测试用例:

shell 复制代码
npm run test

终端输出结果如下:

这里的报错是应该tsd的缘故,为了ts类型兼顾,问题出在了index.test-d.ts,和主程序index.js无关,ts相关知识还得加强,这里就不深纠,为强迫症考虑,可以test指令中移除 tsd

json 复制代码
	"scripts": {
		"test": "xo && ava"
	},

执行之后再终端输出如下:

调试

安装个vscode插件,Code Debugger,可以省去自己配置写调试launch,安装了插件之后再package.jsonscripts上会有调试开关,

package.json里似乎看不出来test指令执行哪个文件,但通过了解一下ava戳这里,这个测试插件默认会执行项目根目录下test.js

那点击之后,执行的是test.js这个测试用例文件,代码如下:

js 复制代码
import test from 'ava';
import arrify from './index.js';

test('main', t => {
	t.deepEqual(arrify('foo'), ['foo']);
	t.deepEqual(arrify(new Map([[1, 2], ['a', 'b']])), [[1, 2], ['a', 'b']]);
	t.deepEqual(arrify(new Set([1, 2])), [1, 2]);
	t.deepEqual(arrify(null), []);
	t.deepEqual(arrify(undefined), []);

	const fooArray = ['foo'];
	t.is(arrify(fooArray), fooArray);
});

测试用例中测试了多种情况,

  1. 传入字符串类型
  2. Map类型
  3. Set类型
  4. null
  5. undefined

在主程序,也就是arrify方法里标注断点,调试就阻断在这儿,说明以上分析的流程正确,也可以在这儿查看传入值的变化情况。

赏析

arrify这个方法进行了4个判断,

  1. 当传入值是null 或者 undefined,直接返回空数组
  2. 传入值是数组类型时,返回其本身
  3. 传入值是字符串类型时,返回一个只包含该字符串的数组
  4. 传入迭代器的情况,主要来分析一下
  5. 传入值都没满足if判断时,例如value是一个对象,一个数字,直接返回数组包含

Synbol.iterator

Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。

ES6中,数组、类数组、Map和Set集合,都具有iterator迭代器接口,意味着他们都是可以被循环遍历的,大白话就是可以支持依次处理该结构的所有成员项。

例如数组:

例如Map:

可以看到,Symbol.iterator会返回一个对象,这就是一个遍历器对象,而作为遍历器对象,其必须具备的特征就是必须具备next()方法。

其中比较特殊的就是字符串的处理 ,它单独占据一个if判断,并没有像数值类型一样直接返回[value],因为字符串类型也可以遍历。

那如果不在迭代器判断之前进行了字符串的判断,会导致字符串类型返回成截断字符串组成的一个数组,

arrify就是为了让传入的值如果是像Map和Set这类结构,返回其自身数据的数组格式。

test.js测试用例调试过程如下:

总结

复习了一下迭代器相关知识,短短十几行的源码也值得认真学习。

相关推荐
gnip1 分钟前
项目开发流程之技术调用流程
前端·javascript
转转技术团队15 分钟前
多代理混战?用 PAC(Proxy Auto-Config) 优雅切换代理场景
前端·后端·面试
南囝coding16 分钟前
这几个 Vibe Coding 经验,真的建议学!
前端·后端
gnip30 分钟前
SSE技术介绍
前端·javascript
yinke小琪44 分钟前
JavaScript DOM节点操作(增删改)常用方法
前端·javascript
枣把儿1 小时前
Vercel 收购 NuxtLabs!Nuxt UI Pro 即将免费!
前端·vue.js·nuxt.js
望获linux1 小时前
【Linux基础知识系列】第四十三篇 - 基础正则表达式与 grep/sed
linux·运维·服务器·开发语言·前端·操作系统·嵌入式软件
爱编程的喵1 小时前
从XMLHttpRequest到Fetch:前端异步请求的演进之路
前端·javascript
喜欢吃豆1 小时前
深入企业内部的MCP知识(三):FastMCP工具转换(Tool Transformation)全解析:从适配到增强的工具进化指南
java·前端·人工智能·大模型·github·mcp
豆苗学前端1 小时前
手把手实现支持百万级数据量、高可用和可扩展性的穿梭框组件
前端·javascript·面试