类数组转换为数组的方法

举报
骁M_M 发表于 2021/05/10 10:52:11 2021/05/10
【摘要】 什么是类数组类数组是可以当作数组来使用的对象,实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。1、属性要为索引(数字)属性,利用属性名(相当于数组下标)模拟数组的特性2、必须有length属性,可以动态增长,相当于数组的length属性3、最好加上Push方法,根据length属性值的位置进行属性的扩充4、还可以加上数组的...

什么是类数组

类数组是可以当作数组来使用的对象,实际应用中,常见的类似数组的对象是 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
}

image.png

类数组的优势

具有对象和数组的特性,既可以当作对象来用,也可以当作数组来用(并不是所有的数组方法都能使用,可以自己手动添加)可以使用for…in遍历类数组对象;

image.png

for…in主要用于遍历对象的可枚举属性。包括自有属性、继承自原型的属性

image.png

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;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。