什么是arrify?
arrify是一种将任何类型的值都能转成数组的js库。
实现效果:
- null --> []
- undefined --> []
- '你好' --> ['你好']
- 55 --> [55]
- new Set('22') --> ['22']
- new Map(2) --> [2]
- [2, 3, 4] --> [2, 3, 4]
等等
如何使用
- 安装
npm install arrify - 在需要使用的js文件内引入即可
import arrify from 'arrify';
console.log(arrify('222')); // ['222']
console.log(arrify(222)); // [222]
console.log(arrify(true)); // [true]
console.log(arrify(null)); // []
console.log(arrify(undefined)); // []
let sym = Symbol(333);
console.log(arrify(sym)); // [Symbol(333)]
let obj = [1, 2, 3];
console.log(arrify(obj)); // [1, 2, 3]
obj = {
name: '姓名',
age: 14
}
console.log(arrify(obj));
// [
// obj = {
// name: '姓名',
// age: 14
// }
// ]
obj = new Date();
console.log(arrify(obj)); // [Mon Jun 13 2022 16:22:55 GMT+0800 (中国标准时间)]
obj = new Set(22);
console.log(arrify(obj)); // Uncaught TypeError: number 22 is not iterable (cannot read property Symbol(Symbol.iterator))
obj = new Set(['23']);
console.log(arrify(obj)); // ['23']
如何自定义实现将一个值转成数组?
通过上面对arrify的介绍,我们知道需要对值的类型进行区分然后进行转换。可以分为以下几类:
- 基本数据类型:string, number, boolean
- 基本数据类型:null, undefined
- 引用数据类型:array, function, obj, date等
核心就是区分数据类型, 以及区分类数组和可迭代对象
什么是类数组对象
- 有length属性
- 有index属性
- 不能使用Array.prototype上定义的方法 常见的类数组就是arguments, 可以使用Array.from将类数组转成数组
什么是可迭代对象
可迭代对象就是可以迭代的对象,通俗地解释就是内部可以循环遍历的对象。主要这几种内置的可迭代项:String, Array, TypedArray, Map, Set。 要使对象变得可以迭代,必须实现一个通过Symbol.iterator的迭代器方法。特别说明:类数组对象也是一种可迭代对象 ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。
因此结合上面我们的了解,可以这样实现:
// 特别说明,对于类数组对象或可迭代对象,如果要转成数组可以使用两种方式
// 1. Array.from(val)
// 2. [...val]
function arrify(val) {
// null和undefined
if(val === null || val === undefined) { return []; }
// 其他基本数据类型
if(typeOf(val) === 'string' || typeOf(val) === 'number' || typeOf(val) === 'boolean' || typeOf(val) === 'symbol') {
return [val];
}
// 类数组对象转成真正的数组
if(Array.isArray(Array.from(val))) {
return [...val];
}
// 可迭代对象,浅拷贝对象创建数组
if(typeof val[Symbol.iterator] === 'function') {
return [...val];
}
return [val] ;
}
arrify是如何实现的?
export default function arrify(value) {
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];
}
arrify的转换规则是
- null和undefined转成空数组
- 数组直接返回
- string类型属于可迭代对象,但是里面的内容不能迭代完再转成数组而是作为一个整体转成数组
- 可迭代对象,遍历迭代,然后浅拷贝转成数组
- 其他类型直接放在数组里面返回。
Symbol.iterator的使用场景?
Symbol.iterator是对象的一个属性,可以根据这个属性上找到一个方法,这个方法会构造一个迭代器来迭代这个对象的值,这个方法就是next()方法。换句话说就是只要对象有Symbol.iterator属性,那么这个对象一定是可迭代对象。 ...展开和for/of循环会自动使用它,我们也可以自定义Symbol.iterator属性为任意对象值定义自己的迭代器,会覆盖默认的迭代器。
let obj = {
name: '赵盼儿',
age: 24
};
obj[Symbol.iterator] = function() {
return {
name: this.name,
age: this.age,
next() {
if (!this.name || !this.age) {
return { done:false, value:'' };
} else {
return { done:true };
}
}
};
};