我正在参与会员专属活动-源码共读第一期,点击参与
学习目标
- 剖析 arrify 函数的源码
- 通过测试用例调试源码
- 学习 Symbol.iterator 的运用场景
- 其它的可迭代目标
拉取源码
进入到 arrify 库房下,运用 CodeSpace 克隆一份项目。
项目目录如图:
忽略掉一些配置文件,各个文件的功用如下:
-
index.js
是整个项目的进口,负责对外导出arrify
函数 -
index.d.ts
是arrify
函数的TS
类型描述文件 -
test.js
是测试用例
剖析源码
arrify函数能够接受一个值,并回来一个包括该值的数组,依据传入不同类型的值回来不同的结果。
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];
}
// 假如传入的值既不是 null/undefined,也不是一个数组/字符串/可迭代目标,函数会回来一个包括该值的数组。
return [value];
}
Symbol.iterator 的运用场景
Symbol.iterator
是 JavaScript 中的一个内置 Symbol,它用于界说一个目标的默认迭代器。当一个目标被用于 for...of
循环或者解构赋值时,会自动调用它的 Symbol.iterator
办法。
举个例子,假设你有一个数组,你能够运用 Symbol.iterator
办法来界说怎么遍历这个数组:
const numbers = [1, 2, 3];
numbers[Symbol.iterator] = function() {
let i = 0;
return {
next: function() {
return {
value: numbers[i] + 1,
done: i++ === numbers.length
};
}
};
};
for (const num of numbers) {
console.log(num);
}
上面的代码界说了一个数组 numbers
,并为它界说了一个 Symbol.iterator
办法,这个办法回来一个迭代器目标,这个目标的 next
办法回来数组的下一个元素。然后我们运用 for...of
循环来遍历这个数组,循环会自动调用 numbers
的 Symbol.iterator
办法来获取每个元素+1后的值。
上面代码履行的履行结果:
可见我们更改了 array 的默认迭代器。
具有默认的迭代器函数的目标
这些目标能够被 for...of
循环遍历
- 数组
- 字符串
- Map(Map)
- Set(Set)
总结
总归,一个数据结构假如具有Symbol.iterator
特点,这个目标就能够被for...of
遍历它的成员。我们理解iteration的原理能够更好运用js供给的数据结构,必要时还能够改造不可迭代的数据结构。