本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
学习目标
arrify 如何转数组
源码地址
源码解读
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 有两个主要的使用场景:
- “隐藏” 对象属性。如果我们想要向“属于”另一个脚本或者库的对象添加一个属性,我们可以创建一个 symbol 并使用它作为属性的键。symbol 属性不会出现在 for..in 中,因此它不会意外地被与其他属性一起处理。并且,它不会被直接访问,因为另一个脚本没有我们的 symbol。因此,该属性将受到保护,防止被意外使用或重写。因此我们可以使用 symbol 属性“秘密地”将一些东西隐藏到我们需要的对象中,但其他地方看不到它。
- JavaScript 使用了许多系统 symbol,这些 symbol 可以作为 Symbol. 访问*。我们可以使用它们来改变一些内建行为。如使用 Symbol.iterator 来进行 迭代 操作,使用 Symbol.toPrimitive 来设置 对象原始值的转换 等等。
从技术上说,symbol 不是 100% 隐藏的。有一个内建方法 Object.getOwnPropertySymbols(obj) 允许我们获取所有的 symbol。还有一个名为 Reflect.ownKeys(obj) 的方法可以返回一个对象的 所有 键,包括 symbol。所以它们并不是真正的隐藏。但是大多数库、内建方法和语法结构都没有使用这些方法。