前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >arrify转数组

arrify转数组

作者头像
赤蓝紫
发布2023-03-02 21:11:14
1540
发布2023-03-02 21:11:14
举报
文章被收录于专栏:clzclz

【源码共读】从arrify的源码中简单复习迭代器

前言

github仓库地址 arrify

这个arrify包的功能就是把一个值转化为数组形式。

开胃菜

代码语言:javascript
复制
export default function arrify(value) {    // 如果值是null或undefined,直接返回空数组    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];}

上面的代码就是本次的源码,只有短短十几行,大概这就是“浓缩的都是精华”吧。上面已经简单地注释了一下。

但是,有两个部分没有任何注释,而这就是本文的核心所在。

先留点悬念:value的类型是string时也是返回[value],最后返回的也是[value],为什么不能共用最后的return [value];呢?(懂的大佬请让一让)

迭代器

上面为什么不共用最后的return [value];就是因为String内置了Iterator接口,也就是说此时value[Symbol.iterator]的类型就是函数,所以,如果共用,那么字符串就会走进去最后的if块里。

那么,这个Iterator接口究竟是什么东西呢?

这个就是迭代器接口,调用该接口,就会返回一个迭代器对象(也可称遍历器对象)。有该接口的数据结构都会有Symbol.iterator属性。

那么,接下来就来简单试验一下(玩一下)。

代码语言:javascript
复制
const str = 'Hello';const gen = str[Symbol.iterator]();console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());

可以看到我们调用Symbol.iterator方法得到迭代器对象,调用next()方法就能遍历该字符串。同理,内置的其他具备Iterator接口的数据结构也能够通过该方法遍历。

如:

  • Array
  • Map
  • Set
  • String
  • 函数的 arguments 对象
  • NodeList 对象

我们也可以自己实现一个迭代器接口,从而能够自定义遍历过程。

代码语言:javascript
复制
const obj = {  count: 0,  [Symbol.iterator]() {    const self = this;    return {      next() {        if (self.count < 5) {          return { value: self.count++, done: false };        } else {          return { value: undefined, done: true };        }      }    }  }};let gen = obj[Symbol.iterator]();console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());console.log(gen.next());

扩展运算符的作用

上面我们是通过调用迭代器接口,得到遍历器对象,然后调用遍历器对象的next()方法来实现遍历。所以如果我们想让有Iterator接口的数据接口转换成数组就很麻烦。

但是实际上我们使用扩展运算符就能很简单的将可迭代对象转换成数组。

代码语言:javascript
复制
const str = 'Hello';console.log([...str]);    // [ 'H', 'e', 'l', 'l', 'o' ]const set = new Set([1, 2, 3, 2, 1, 4]);console.log([...set]);    // [ 1, 2, 3, 4 ]

从上面的例子也能看出为什么将字符串和其他的可迭代对象分开。如果不分开,那么得到的数组将会是将字符串拆解后的数组,实际上意义并不大。如果想要这种效果,也可以单独使用扩展运算符处理,毕竟工具函数不可能考虑所有的使用情境。

测试源码

代码语言:javascript
复制
import arrify from "arrify";console.log(arrify(undefined));console.log(arrify(null));console.log(arrify('Hello'));console.log(arrify([1, 2, 3, 4]));console.log(arrify(new Set([1, 2, 3, 2, 1, 4])));console.log(arrify(new Map([  ['name', 'clz'],  ['age', '21']])));

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【源码共读】从arrify的源码中简单复习迭代器
    • 前言
      • 开胃菜
        • 迭代器
          • 扩展运算符的作用
        • 测试源码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档