类数组转换为数组的方法
什么是类数组
类数组是可以当作数组来使用的对象,实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。
1、属性要为索引(数字)属性,利用属性名(相当于数组下标)模拟数组的特性
2、必须有length属性,可以动态增长,相当于数组的length属性
3、最好加上Push方法,根据length属性值的位置进行属性的扩充
4、还可以加上数组的其他方法,如splice、pop、shift…(不加则不能调用)
let obj = {
'0':'aaa',
'1':'bbb',
'2':'cccc',
'length':'3',
'push':Array.prototype.push,
'name':'yin',
'splice':Array.prototype.splice
}
类数组的优势
具有对象和数组的特性,既可以当作对象来用,也可以当作数组来用(并不是所有的数组方法都能使用,可以自己手动添加)可以使用for…in遍历类数组对象;
for…in主要用于遍历对象的可枚举属性。包括自有属性、继承自原型的属性
Object.key():返回对象自身的所有可枚举的属性
我们有一种需求就是把类数组对象转化为数组对象,下面我们看一下这些方法。
1.创建新数组,把类数组的元素添加到新数组中;
如果目标数组只是为了得到对象的key的集合或者value的集合还是相对容易的
let obj = {'未完成':5, '已完成':8, '待确认':4, '已取消':6};
var arr = []
for (let i in obj) {
arr.push(obj[i]); //属性
//arr.push(obj[i]); //值
}
console.log(arr);
如果想将对象转换成数组
var arr = []
for (let i in obj) {
let o = {};
o[i] = obj[i];
arr.push(o)
}
console.log(arr);
2.通过Array.prototype.slice.call()将类数组对象传入即可
Array.prototype.slice.call(arrayLike)
这种方法是借用了数组原型中的slice方法,返回一个数组。slice方法的内部实现:
var result = new Array();
start = start || 0;
end = end || this.length; //使用call之后this指向了类数组对象
for(var i = start; i < end; i++){
result.push(this[i]);
}
return result;
原理是数组的slice()方法可以从已有数组中返回一个新数组,它可以接受两个参数arr.slice(start,end),第一个参数规定从何处开始选取,第二个参数表示从何处选取结束,如果不传参将返回原数组的一个副本,但该方法不会修改原数组,而是返回截取的新数组,根据这个就可以将类数组转化成数组对象啦!
slice() 方法可从已有的数组中返回选定的元素。
arrayObject.slice(start,end),返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
3.es6中的新方法Array.from()
Array.from()是ES6中新增的方法,可以将两类对象转为真正的数组:类数组对象和可遍历(iterable)对象(包括ES6新增的数据结构Set和Map)。
var arrayLike = {
'0':'a',
'1':'b',
'2':'c',
length:3
}
var arr = Array.from(arrayLike);//['a','b','c']
//把NodeList对象转换为数组
let ps = document.querySelectorAll('p');
Array.from(ps).filter(p => {
return p.textContent.length > 100;
});
//转换arguments对象为数组
function foo(){
var args = Array.from(arguments);
}
//只要是部署了Iterator接口的数据结构,Array.from都能将其转换为数组
Array.from('hello'); //['h','e','l','l','o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']
字符串和 Set 结构都具有 Iterator 接口,因此可以被Array.from转为真正的数组。
如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组。
Array.from([1, 2, 3])
// [1, 2, 3]
4.扩展运算符(…)
同样是ES6中新增的内容,扩展运算符(…)也可以将某些数据结构转为数组
//arguments对象的转换
function foo(){
var args = [...arguments];
}
//NodeList对象的转换
[...document.querySelectorAll('p')]
扩展运算符实际上调用的是遍历器接口,如果一个对象没有部署此接口就无法完成转换
Array.from与扩展运算符的区别
Array.from方法还支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
上面代码中,Array.from返回了一个具有三个成员的数组,每个位置的值都是undefined。扩展运算符转换不了这个对象。
Array.from
Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
下面的例子是取出一组 DOM 节点的文本内容。
let spans = document.querySelectorAll('span.name');
// map()
let names1 = Array.prototype.map.call(spans, s => s.textContent);
// Array.from()
let names2 = Array.from(spans, s => s.textContent)
下面的例子将数组中布尔值为false的成员转为0。
Array.from([1, , 2, , 3], (n) => n || 0)
// [1, 0, 2, 0, 3]
另一个例子是返回各种数据的类型。
function typesOf () {
return Array.from(arguments, value => typeof value)
}
typesOf(null, [], NaN)
// ['object', 'object', 'number']
如果map函数里面用到了this关键字,还可以传入Array.from的第三个参数,用来绑定this。
Array.from()可以将各种值转为真正的数组,并且还提供map功能。这实际上意味着,只要有一个原始的数据结构,你就可以先对它的值进行处理,然后转成规范的数组结构,进而就可以使用数量众多的数组方法。
Array.from({ length: 2 }, () => 'jack')
// ['jack', 'jack']
上面代码中,Array.from的第一个参数指定了第二个参数运行的次数。这种特性可以让该方法的用法变得非常灵活。
Array.from()的另一个应用是,将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF的 Unicode 字符,算作两个字符的 bug。
function countSymbols(string) {
return Array.from(string).length;
}
- 点赞
- 收藏
- 关注作者
评论(0)