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

124 阅读3分钟

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

学习目标

arrify 如何转数组

源码地址

github.com/sindresorhu…

线上阅读

源码解读

export default function arrify(value) {
	if (value === null || value === undefined) {
		return [];
	}
//null或者undefinde直接返回[]
	if (Array.isArray(value)) {
		return value;
	}
//用Array.isArray判断是否是数组,是直接返回输入值
	if (typeof value === 'string') {
		return [value];
	}
//字符串返回长度为一数组
	if (typeof value[Symbol.iterator] === 'function') {
		return [...value];
	}
//判断是否是可迭代对象,是的话使用展开运算符转化为数组
	return [value];
}

知识点学习

Iterable object(可迭代对象)

可以应用 for..of 的对象被称为 可迭代的

技术上来说,可迭代对象必须实现 Symbol.iterator 方法。

  • objSymbol.iterator 的结果被称为 迭代器(iterator) 。由它处理进一步的迭代过程。
  • 一个迭代器必须有 next() 方法,它返回一个 {done: Boolean, value: any} 对象,这里 done:true 表明迭代结束,否则 value 就是下一个值。
  • 内建的可迭代对象例如字符串和数组,都实现了 Symbol.iterator

Array.from(obj[, mapFn, thisArg]) 将可迭代对象 转化为真正的数组 Array。

symbol 类型

symbol 是唯一标识符的基本类型

根据规范,只有两种原始类型可以用作对象属性键:

  • 字符串类型
  • symbol 类型

symbol 总是不同的值,即使它们有相同的名字。如果我们希望同名的 symbol 相等,那么我们应该使用全局注册表:Symbol.for(key) 返回(如果需要的话则创建)一个以 key 作为名字的全局 symbol。使用 Symbol.for 多次调用 key 相同的 symbol 时,返回的就是同一个 symbol。

symbol 有两个主要的使用场景:

  1. “隐藏” 对象属性。如果我们想要向“属于”另一个脚本或者库的对象添加一个属性,我们可以创建一个 symbol 并使用它作为属性的键。symbol 属性不会出现在 for..in 中,因此它不会意外地被与其他属性一起处理。并且,它不会被直接访问,因为另一个脚本没有我们的 symbol。因此,该属性将受到保护,防止被意外使用或重写。因此我们可以使用 symbol 属性“秘密地”将一些东西隐藏到我们需要的对象中,但其他地方看不到它。
  2. JavaScript 使用了许多系统 symbol,这些 symbol 可以作为 Symbol. 访问*。我们可以使用它们来改变一些内建行为。如使用 Symbol.iterator 来进行 迭代 操作,使用 Symbol.toPrimitive 来设置 对象原始值的转换 等等。

从技术上说,symbol 不是 100% 隐藏的。有一个内建方法 Object.getOwnPropertySymbols(obj) 允许我们获取所有的 symbol。还有一个名为 Reflect.ownKeys(obj) 的方法可以返回一个对象的 所有 键,包括 symbol。所以它们并不是真正的隐藏。但是大多数库、内建方法和语法结构都没有使用这些方法。