《arrify源码》阅读笔记
-
我正在参与掘金会员专属活动-源码共读第一期,点击参与
-
本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与
-
这是源码共读的第33期,链接:juejin.cn/post/710021…
源码目录总览
index.js是整个项目的入口,负责对外导出arrify函数index.d.ts是一个typescript的描述文件,里面定义了arrify函数的类型test.js是测试用例文件,测试代码是使用ava这个测试框架写的index.test-d.ts是针对定义类型的测试用例文件,使用tsd库进行编写.npmrc是npm的配置文件
1.源代码
export default function arrify(value) {
// 针对特殊值做判断,返回空数组
if (value === null || value === undefined) {
return [];
}
// 如果传入的值本身就是数组,不做修改,直接返回
if (Array.isArray(value)) {
return value;
}
// 如果传入的值是 string 类型,就把这个值放在一个空数组中,并返回这个新数组
if (typeof value === 'string') {
return [value];
}
// 如果传入的值有可以访问的默认迭代器函数,就对这个值进行遍历
// 再将遍历后的值放在一个空数组中,并返回这个新数组
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
// 不包含以上情况的,直接将这个值放在一个空数组中,并返回这个新数组
return [value];
}
这里可以看到,处理 string 类型的值与 处理任意类型的值的逻辑是一样的,那么为什么还需要为 string 类型单独写一个 if判断呢?
首先我们需要知道的是,在ES6中,可以通过Symbol.iterator获取对象的默认迭代器函数,拥有迭代器函数的对象可以通过遍历的方式获取其中的值。
查阅MDN的文档可知,以下5个内置类型具有默认的迭代器函数,分别是:
- Array(数组)
- TypedArray(类型数组):描述了底层二进制数据缓冲区的类数组视图
- String(字符串)
- Map(Map):不包含
WeakMap类型 - Set(Set):不包含
WeakSet类型
由此可以得知,string类型是拥有默认的迭代器函数的,所以当我们去遍历一个字符串时,会得到这样的结果:
const string = 'test string';
for(let i = 0; i<string.length; i++) {
console.log(string[i])
}
// 依次输出 t e s t s t r i n g
这样的结果和我们期望将一个字符串转为数组的结果是不符的,所以在arrify中的处理时,不使用string默认的字符串迭代之后的结果,而是将字符串放在一个空数组中并返回。