前言
- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
- 这是源码共读的第33期,链接:juejin.cn/post/710021…
arrify介绍
将一个值转换为数组
如何使用
// 1. install arrify package
npm install arrify
// 2. import
import arrify from 'arrify';
arrify('🦄');
//=> ['🦄']
arrify(['🦄']);
//=> ['🦄']
arrify(new Set(['🦄']));
//=> ['🦄']
arrify(null);
//=> []
arrify(undefined);
//=> []
源码解读
export default function arrify(value) {
// 如果value为null或者undefined,则返回空数组
if (value === null || value === undefined) {
return [];
}
// 如果value本来就是一个数组,则返回该数组
if (Array.isArray(value)) {
return value;
}
// 单独处理了字符粗
if (typeof value === 'string') {
return [value];
}
// 如果value存在Symbol.iterator属性,则使用扩展运算符展开value的值并返回新的数组
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
return [value];
}
为啥变量包含Symbol.iterator属性,就可以使用...扩展运算符?
1. Symbol和Symbol.iterator属性介绍
- Symbol是ES6引入的一种新的原始数据类型,表示独一无二的值
- Symbol值作为对象的属性名时,遍历对象的时候,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringfy()返回,但是,有一个Object.getOwnPropertySymbols()方法,可以获取指定对象的所有Symbol属性名。
- Symbol.iterator是ES6提供的内置的Symbol值,对象的Symbol.iterator属性,指向该对象的默认迭代器方法(Iterator)。
2. Iterator迭代器的概念
- Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令
for...of循环,Iterator 接口主要供for...of消费。 参照阮一峰老师的Iterator和for...of 循环写的非常详细 - 一种数据结构只要部署了iterator接口,我们就说这种数据结构是可遍历的,ES6 规定,默认的 Iterator 接口部署在数据结构的
Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”,例如下图的数组原生就部署了Iterator接口可以更改原生的Iterator接口,如下图
有一些场合会默认调用 Iterator 接口(即
Symbol.iterator方法),如下 - 对数组和Set结构进行结构赋值时,会默认调用Symbol.iterator
- 扩展运算符...
- yield*
- for...of
- Array.from()
- Map()、Set()、WeakMap()、WeakSet()
- Promise.all()
- Promise.race()
总结
Symbol.iterator和迭代器的知识点较多,需要多多实践