JavaScript集合对象遍历方法总结
2017-08-30 16:34
633 查看
在JavaScript中能表示集合的数据结构是对象,如数组、普通对象和ES2015中新增的Set和Map等。当然不同对象的表现形式和功能不一样。如对于集合
其实对数组来说,最有效率的方式就是第一种简单for循环了。另外几种虽然可以,但是效率就大打折扣了。for…of循环是ES6新增的方法,用在这里有点大材小用了,不过在这里主要说明的是ES6的数组、Set和Map都拥有
有些数据结构是在现有数据结构的基础上,计算生成的。比如,ES6的数组、Set、Map 都部署了以下三个方法,调用后都返回遍历器对象。
entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
keys() 返回一个遍历器对象,用来遍历所有的键名。
values() 返回一个遍历器对象,用来遍历所有的键值。
对象的遍历可以通过for…in循环得到。如果只想得到对象的属性值,可以用Object提供的静态方法
我来解释一下,先来看一下上面的黑体字,返回可枚举的属性。这意味着只有可枚举的属性才会暴露出来。那怎么看是不是可枚举呢?要查看对象属性的特性,可以用
另外针对
Set和Map的加入可谓是呼声已久。因为很长时间我们都只能依靠普通对象来实现Set和Map的功能。所以如果JS原生支持的话,那再好不过了。Set的遍历可以用for…of或forEach来实现。如果使用set.entries(),返回的数组键名和键值相等。
得益于ES6的方法,数组和Set可以迸发出很强大能量。比如数组转Set,直接向Set的构造函数中传递数组就会得到一个去重的Set;Set转数组,同样很简单,直接使用Array.from或扩展运算符就Ok了。(扩展运算符可以将任何实现了 Iterator 接口的对象转化为数组,Set实现了 Iterator 接口。)二者简直天作之合。比如有些时候需要对数组去重而后排序,二者合作简直不能太美。
for…of做map的遍历时,默认方式是返回键值对,同使用map.entries()相同,不过可以通过使用
Map和数组的转换同样简单:
好了,这就是本文的内容。不过,另外说一下只有提供Iterator 接口的数据结构才可以使用for…of循环,才可以使用扩展操作符转化为数组。原生具备该接口的有:
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
对于Set和Map更多的用法请自行查看文末的参考资料。
如有错误,请不吝指正;如有问题,请写下评论。
参考资料:
1. ECMAScript 6 入门
{1,2,3,4,5,1},数组的表现形式可以为
[1,2,3,4,5,1],普通对象的表现形式可以是
{"1":2,"2":1,"3":1,"4":1,"5":1},Set的表现形式是
{1,2,3,4,5},Map的表现形式为
{"1" => 2, "2" => 1, "3" => 1, "4" => 1, "5" => 1}。当然set的主要作用是去重,map的主要作用是统计。新增的数据结构和新增的方法也使得集合的遍历变得很容易。针对这样的对象,我们经常使用的操作就是遍历,本文将总结集合对象遍历的几种方式。
1. 数组的遍历
首先来看一下针对数组的遍历方法,如下:var arr=[1,2,3,4,5,1]; //1.简单的for循环 for(var i=0,l=arr.length;i<l;i++){ console.log(`${i}:${arr[i]}`); } //2.forEach循环 arr.forEach((item,index)=>console.log(`${item}:${arr[index]}`)); //3.for...in循环 for(var i in arr){ console.log(`${i}:${arr[i]}`) } //4.for...of循环 //只输出值 for(var i of arr){ console.log(`${i}`) } //输出索引和值 for(var [key,value] of arr.entries()){ console.log(`${key}:${value}`) } //outputs: 0:1 1:2 2:3 3:4 4:5 5:1
其实对数组来说,最有效率的方式就是第一种简单for循环了。另外几种虽然可以,但是效率就大打折扣了。for…of循环是ES6新增的方法,用在这里有点大材小用了,不过在这里主要说明的是ES6的数组、Set和Map都拥有
entries()方法,它返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。这点可以参见阮一峰老师的《ECMAScript 6 入门》,引用如下:
有些数据结构是在现有数据结构的基础上,计算生成的。比如,ES6的数组、Set、Map 都部署了以下三个方法,调用后都返回遍历器对象。
entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
keys() 返回一个遍历器对象,用来遍历所有的键名。
values() 返回一个遍历器对象,用来遍历所有的键值。
2. 对象的遍历
var obj={"1":2,"2":1,"3":1,"4":1,"5":1}; //1. for...in循环 for(var i in obj){ console.log(`${i}:${obj[i]}`) } //2. 利用Object.keys()+forEach Object.keys(obj).forEach(i=>console.log(`${i}:${obj[i]}`)); //outputs: 1:2 2:1 3:1 4:1 5:1
对象的遍历可以通过for…in循环得到。如果只想得到对象的属性值,可以用Object提供的静态方法
Object.keys()得到。不过这里要说一下for…in循环。for…in循环会返回所有能够通过对象访问的、可枚举(enumerated)的属性,其中既包括存在于实例中的属性,也包括存在与原型中的属性。它准确来说是用来找属性的方法,用在集合遍历(属性值的数据类型通常一样)显得有些大材小用了。不过因为这是一个很强大的方法,强大也意味着容易让人犯错。比如你想造一个类数组对象(对象中有length属性)写了如下语句
obj.length=5。当你再用for…in循环是就会郁闷的发现输出多了一个
length:5。或许你也许会问数组也是对象,为什么for…in循环的结果没有length呢?
我来解释一下,先来看一下上面的黑体字,返回可枚举的属性。这意味着只有可枚举的属性才会暴露出来。那怎么看是不是可枚举呢?要查看对象属性的特性,可以用
Object.getOwnPropertyDescriptor()。比如我们查看length属性在数组中是否可枚举,可使用如下代码:
Object.getOwnPropertyDescriptor(arr,'length')。它在Chrome中的返回为
Object {value: 6, writable: true, enumerable: false, configurable: false}。里面的enumerable值为false,意味着不可枚举。configurable为false说明不可删除。所以length属性在数组中默认是不可枚举,也不能用delete删除的。那有没有办法修改哪?要修改属性默认的特性,可以使用
Object.defineProperty()。但数组中的length属性默认是不可修改的。说了这么多,我们给对象新添加的length属性返回什么呢?试一下,就会发现它返回
Object {value: 4, writable: true, enumerable: true, configurable: true}。因为configurable值为true,所以可被枚举到。不过针对我们自己创建的对象,可以修改属性类型。使用
Object.defineProperty(obj,'length',{enumerable: false})设置可枚举为false之后,发现再利用for…in循环就不会再遍历到length属性了。这里的属性类型的具体内容可以参见JavaScript高级程序设计6.1节。
另外针对
Object.keys()要注意,若传入的参数为非对象,ES6工作方式同ES5不一样。ES5会报错,ES6会将其强制转换为对象,若转换不成功报错。
Object.keys('abcd') //es5:TypeError... //es6:["0", "1", "2", "3"]
3. Set的遍历
//Set作为构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数 var set=new Set([1,2,3,4,5,1]) //Set {1, 2, 3, 4, 5} //也可以使用add方法添加成员 var set=new Set(); set.add(1); set.add(2); set.add(3); set.add(4); set.add(5); set.add(1); //Set {1, 2, 3, 4, 5} //1.for...of遍历值 for(var i of set){ console.log(`${i}`) } for(var [key,value] of set.entries()){ console.log(`${key}:${value}`) } //2.forEach遍历键值对 set.forEach((value, key) => console.log(`${key}:${value}`) )
Set和Map的加入可谓是呼声已久。因为很长时间我们都只能依靠普通对象来实现Set和Map的功能。所以如果JS原生支持的话,那再好不过了。Set的遍历可以用for…of或forEach来实现。如果使用set.entries(),返回的数组键名和键值相等。
set.keys()和
set.values()也会得到相同的集合。
得益于ES6的方法,数组和Set可以迸发出很强大能量。比如数组转Set,直接向Set的构造函数中传递数组就会得到一个去重的Set;Set转数组,同样很简单,直接使用Array.from或扩展运算符就Ok了。(扩展运算符可以将任何实现了 Iterator 接口的对象转化为数组,Set实现了 Iterator 接口。)二者简直天作之合。比如有些时候需要对数组去重而后排序,二者合作简直不能太美。
var arr=[5,3,1,2,3,4,5,1]; var set=new Set(arr); //Set {5,3,1,2,4} arr=Array.from(set); //也可以使用扩展运算符arr=[...set]; arr.sort((a,b)=>a-b); //output:[1, 2, 3, 4, 5]
4. Map的遍历
//Map作为构造函数可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组 var map=new Map([["小明",2],["小红",2]]) //Map {"小明" => 2, "小红" => 2} //也可以使用set设置键值对 var map=new Map(); map.set(1,2); map.set(2,1); map.set(3,1); map.set(4,1); map.set(5,1); //Map {1 => 2, 2 => 1, 3 => 1, 4 => 1, 5 => 1} //1.for...of遍历 //遍历键值对 for(var [key,value] of map){ console.log(`${key}:${value}`) } //遍历值 for(var value of map.values()){ console.log(`${value}`) } //遍历键 for(var key of map.keys()){ console.log(`${key}`) } //2.forEach遍历键值对 map.forEach((value, key) => console.log(`${key}:${value}`) )
for…of做map的遍历时,默认方式是返回键值对,同使用map.entries()相同,不过可以通过使用
map.keys()或
map.values()只返回键名或键值。Map和Set都提供forEach接口,和数组使用方式相同。
Map和数组的转换同样简单:
//数组转map var arr=[["小明",2],["小红",2]]; var map=new Map(arr) //{"小明" => 2, "小红" => 2} //map转数组 arr=[...map]; //[Array[2], Array[2]]
好了,这就是本文的内容。不过,另外说一下只有提供Iterator 接口的数据结构才可以使用for…of循环,才可以使用扩展操作符转化为数组。原生具备该接口的有:
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
对于Set和Map更多的用法请自行查看文末的参考资料。
如有错误,请不吝指正;如有问题,请写下评论。
参考资料:
1. ECMAScript 6 入门
相关文章推荐
- javascript入门·对象属性方法大总结
- javascript引用对象的方法 (总结)
- java中List对象集合的遍历方法
- JavaScript 内置对象属性及方法集合
- javascript操作正则表达式对象的方法总结
- JavaScript中Stringd对象方法总结
- 关于Javascript与表单结合时出现"对象不支持此属性或方法"的问题总结(不断更新中...)
- JavaScript中判断对象类型的几种方法总结
- javascript遍历对象属性和方法
- C#中遍历各类数据集合的方法总结
- java中List、Set、Map集合的遍历方法总结
- Javascript遍历JavaScript某个对象所有的属性名称和值的方法
- JavaScript中判断对象类型的几种方法总结
- javascript中创建对象的几种方法总结
- Javascript 定义类或对象的方法总结
- JavaScript中创建类/对象的几种方法总结
- jquery技巧总结-jQuery对象,集合,方法扩展,事件处理,特效,解决冲突
- javascript中创建对象的几种方法总结
- javaScript获取对象集合(另一种方法)
- javascript中遍历List集合对象