【源码读】【若川视野 x 源码共读】第33期 | A24 |arrify 转数组

125 阅读2分钟

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

源码共读前言

本文目标

  • 学习 Symbol.iterator 的使用场景
  • 学会通过测试用例调试源码
    • 发布npm包
    • esm
    • 测试用例

源码

export default function arrify(value) {
    if (value === null || value === undefined) {
        return [];
    }

    if (Array.isArray(value)) {
        return value;
    }

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

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

    return [value];
}

知识点

1. typeof

主要针对基础类型和对象类型,以及undefinednull 更多参考

2. Symbol.iterator

包括:数组 ( Array ) 和类型数组 ( TypedArray )、Map、Set、String、类数组对象(Arguments、NodeList)

特性:

  1. 可以应用 for..of 的对象被称为 可迭代的;
  2. 必须有 next() 方法,它返回一个 {done: Boolean, value: any} 对象,这里 done:true 表明迭代结束,否则 value 就是下一个值。
  3. Symbol.iterator 方法会被 for..of 自动调用,也可以直接调用它。

更多参考

根据以上特性,做如下思考:

  1. 既然string也是可迭代对象,源码中针对string类型的判断是不是可以移除?
  2. 既然Array也是可迭代对象,源码中针对Array类型的判断是不是可以移除?

测试疑问【1】: 移除string类型的判断后,'foo' 被转为['f','o','o'],不符合需求,显然string此时被当成可迭代对象,遍历出每个字符;故不可移除

测试疑问【2】: 移除Array类型的判断后,经测试未发现异常,所以此处暂时存疑?也可能是提高代码可读性

3. 代码测试Test

测试代码片段

import test from 'ava';
import arrify from './index.js';

test('main', t => {
    const stringArray = arrify('foo');
    t.deepEqual(stringArray, ['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', 1, [1, 'dd']];
    const fooArrayResult = arrify(fooArray);
    t.is(fooArrayResult, fooArray);
});

命令Test的三个包:xotsdava(nodejs 测试工具)

xo:JavaScript/TypeScript linter (ESLint wrapper) with great defaults JavaScript/TypeScript linter(ESLint 包装器)具有很好的默认值

tsd:Check TypeScript type definitions 检查 TypeScript 类型定义

ava:Node.js test runner that lets you develop with confidence

总结

  1. 基础需要稳固,稳固而知新
  2. 学习源码思想,多想想为什么?多参考他人的笔记思路
  3. 贵在坚持,勿以善小而不为

参考文章

1、typeof

2、Symbol.iterator迭代器

3、Symbol.iterator迭代器

4、Symbol.iterator迭代器