作为一个前端工程师,经常会遇见转换成数组的需求,被转换的对象有可能是String、Set()、null、Map()、undefined、或者是数组本身。我们最经常的做法就是写一个arrify函数帮我去进行转换。久而久之因为经常会做不同的项目中遇到同样的需求所以我们通常会把他封装成一个npm包发布出去,方便于代码的重复应用,和引用。
那arrify包我们就经常用了,那你知道arrify包里面的代码是怎么执行的吗?接下来就跟我一起好好分析一下源码!
arrify源码
既然是要了解它是如何执行的,那就得从源码入手。老规矩先上源码!
JavaScript源码
export default function arrify(value) {
//判断是否是否是null,或者undefined
if (value === null || value === undefined) {
return [];
}
//判断是否是数组
if (Array.isArray(value)) {
return value;
}
//判断是否是string
if (typeof value === 'string') {
return [value];
}
//判断是否是Set()、Map()
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
//用数组的形式返回我们的value
return [value];
}
在JavaScript的源码中我们可以很明显的看见,在arrify函数中,利用if
对函数接收的值进行判断。
-
如果函数接收的值是null,或者undefined,直接返回一个空数组。
-
如果函数接收的值是一个数组(利用
Array.isArray(value)
进行判断,数组自带的一个判断方法,如果传入的值是数组就就会返回true,否则返回false),直接返回自身。 -
如果函数接收的值是string(
typeof value === 'string'
利用typeof
进行判断),把接收的值放在数组里进行返回 -
如果函数接收的值是Set()、Map()(利用
typeof value[Symbol.iterator] === 'function'
利用typeof
与[Symbol.iterator]
进行判断,),解构Set()里的值放到数组中进行返回(利用ES6的结构语法...
)。
测试
当然我们写出一个函数当时少不了测试环节,对函数的功能进行测试是必不可少的。那如果我们用人工的方式进行测试将每一种类型的值都传入然后将返回结果打印在控制台来测试很明显是一件吃力不讨好的事,特别是在我们的项目特别巨大的时候,功能特别复杂的时候,更加是不合理的方式。
那我们要如何在用最轻松的方式去获得准确的测试结果呢?
自动化测试工具AVS,
那我们在arrify中应该如何利用ava去编写自动化测试呢?
那为什么是AVA呢?
- 轻量化和效率高
- 语法简单,编写轻松
- 并发运行测试运行效率高
- 包含 TypeScript 和 Flow 的类型定义
首先我们要安装AVA插件
npm init ava
然后我们要在我们的package.json
中修改我们的scripts
执行脚本
{
"scripts": {
"test": "ava "
},
接下来我们就要开始编写我们的测试脚本test
了
- 首先我们要从到ava中导入我们的test方法和我们编写的arrify 函数
import test from 'ava';
import arrify from './index.js';
- 然后我们要利用我们导入的test方法进行测试。
- 第一个参数是我们测试的名称
- 第二个参数要求是一个传入的是一个回调函数,在回调函数里编写我们的测试语法
test('测试名称', t => {
...测试语法
});
- 然后我们要用
t.deepEqual()
函数来编写我们的测试代码- 第一个参数是我们测试的
输入值
- 第二个参数是我们测试的输出
参考值
,如果得到的返回值
和参考值
相同测试就通过,否则相反
- 第一个参数是我们测试的
import test from 'ava';
import arrify from './index.js';
test('main', t => {
//输入一个'foo'字符串,返回结果应该是['foo']
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);
});
测试结果
还有一些相关知识:
- npm的发布可以阅读我这篇文章:手把手,带你发布你的第一个npm包
- Symbol.iterator和Symbol.asyncIterator的相关知识