- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
- 这是源码共读的第33期,链接:arrify转数组
前言
这是第一次参与源码共读活动,希望通过源码阅读能对代码实现有更进一步的了解,继而提高自己的编码水平。
源码地址
- github仓库地址 arrify
- github1s: github1s.com/sindresorhu…
前期准备
- 下载源码
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 循环使用。
断点调试一下typeof value[Symbol.iterator] === 'function'这行代码:
发现value循环迭代了两次,说明当传入值是如map、set等内置可迭代对象,会重复调用next()显式地迭代;然后利用解构把传入值转成数组形式传递出去。
总结
通过对arrify源码包的分析,了解了package.json的标签作用,掌握了代码调试的技巧,以及实践了symbol.iterator的应用,以上是个人对arrify源码的一些解读,有不对之处劳请指出!