《arrify源码》阅读笔记

174 阅读2分钟

《arrify源码》阅读笔记

源码目录总览

源码目录总览
  • index.js是整个项目的入口,负责对外导出arrify函数
  • index.d.ts是一个typescript的描述文件,里面定义了arrify函数的类型
  • test.js是测试用例文件,测试代码是使用ava这个测试框架写的
  • index.test-d.ts是针对定义类型的测试用例文件,使用tsd库进行编写
  • .npmrcnpm的配置文件

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内置类型中具有默认迭代器函数的类型

查阅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默认的字符串迭代之后的结果,而是将字符串放在一个空数组中并返回。

2.测试用例

测试用例图片

3.类型定义

类型定义