源码共读之arrify

1,191 阅读3分钟

image.png

前言

这是第一次参与源码共读活动,希望通过源码阅读能对代码实现有更进一步的了解,继而提高自己的编码水平。

源码地址

前期准备

  • 下载源码
    git clone https://github.com/sindresorhus/arrify.git
    
  • 安装依赖
    yarn / npm install
    

目录结构分析

- .github                   github相关配置
    - workflows
    - funding.yml
    - security.md
 - .editorconfig            编辑器相关
 - .gitattributes
 - .gitignore               提交忽略文件配置
 - .npmrc                   npm指令配置
 - index.d.ts               arrify源码ts版本
 - index.js                 arrify源码js版本
 - index.test-d.ts          测试用例ts版本
 - license                  证书
 - package.json             依赖包配置文件
 - readme.md                使用说明
 - test.js                  测试用例js版本

package.json分析

{
   "name": "arrify", //文件名
   "version": "3.0.0",//版本号
   "description": "Convert a value to an array",//项目描述
   "license": "MIT",
   "repository": "sindresorhus/arrify",
   "funding": "https://github.com/sponsors/sindresorhus",
   "author": {
   	"name": "Sindre Sorhus",
   	"email": "sindresorhus@gmail.com",
   	"url": "https://sindresorhus.com"
   },// 作者
   "type": "module",// 模块化规范
   "exports": "./index.js",//npm包的真实导出
   "engines": {
   	"node": ">=12"
   },
   "scripts": {
   	"test": "xo && ava && tsd"
   },//自定义脚本
   "files": [
   	"index.js",
   	"index.d.ts"
   ],//文件
   "keywords": [
   	"array",
   	"arrify",
   	"arrayify",
   	"convert",
   	"value",
   	"ensure"
   ],
   "devDependencies": {
   	"ava": "^3.15.0",
   	"tsd": "^0.14.0",
   	"xo": "^0.39.1"
   }// 开发依赖
}

几个关键标签

  • scripts---定义脚本命令 拓展知识:当前目录的node_modules/.bin子目录里面的所有脚本都可以直接调用,不必加上路径【每当制定npm run的时候,就会自动创建一个shell脚本,这里需要注意的是,npm run新建的这个 Shell,会将本地目录的node_modules/.bin子目录加入PATH变量。】

    这里只有一个test命令,执行命令:yarn test / npm run test 进行测试
  • type---定义模块化规范 拓展知识:①不指定type的时候,type的默认值是commonjs,不过建议npm包都指定一下type;②当type字段指定值为module则采用ESModule规范;③当type字段指定时,目录下的所有.js后缀结尾的文件,都遵循type所指定的模块化规范;④除了type可以指定模块化规范外,通过文件的后缀来指定文件所遵循的模块化规范,以.mjs结尾的文件就是使用的ESModule规范,以.cjs结尾的遵循的是commonjs规范

  • devDependencies---开发依赖,提高开发效率 拓展知识:①dependencies--项目依赖;②peerDependencies--package.json依赖项,解决核心库重复下载以及统一核心库版本问题;③peerDependenciesMeta--详细修饰peerDependencies,相当于对peerDependencies的补充说明

源码分析

export default function arrify(value) {
	if (value === null || value === undefined) {
		return [];
	} // null或undefinded返回空数组

	if (Array.isArray(value)) {
		return value;
	} // 数组类型返回自身

	if (typeof value === 'string') {
		return [value];
	}

	if (typeof value[Symbol.iterator] === 'function') {
		return [...value];
	}

	return [value];
}

核心代码不多,主要思想是判断传入值类型,再根据类型做相应的处理最后确保返回传入值的数组形式;比较值得关注的点应该是Array.isArray判断数组类型,以及typeof、Symbol.iterator的应用。

关于typeof

提到typeof,就有必要提一下js的基础数据类型:

  • 基础类型:①number ②string ③boolean ④undefined ⑤null ⑥symbol ⑦bigint;其中symbol属性值唯一,不能与其他数据进行计算;
  • typeof作用及作用:检测所属类型,typeof不能正确检测nulll,除可调用对象/函数【构造函数、生成器函数、普通函数】会返回function;其余的对象数据会返回object

关于Symbol.iterator

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

image.png 断点调试一下typeof value[Symbol.iterator] === 'function'这行代码: 图片.png 图片.png 发现value循环迭代了两次,说明当传入值是如map、set等内置可迭代对象,会重复调用next()显式地迭代;然后利用解构把传入值转成数组形式传递出去。

总结

通过对arrify源码包的分析,了解了package.json的标签作用,掌握了代码调试的技巧,以及实践了symbol.iterator的应用,以上是个人对arrify源码的一些解读,有不对之处劳请指出!

参考文献