本帖最后由 hechengjin 于 2016-1-6 16:58 编辑
遍历数组:
ES6提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象(《Iterator》),可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
- for (let index of ['a', 'b'].keys()) {
- console.log(index);
- }
- // 0
- // 1
- for (let elem of ['a', 'b'].values()) {
- console.log(elem);
- }
- // 'a'
- // 'b'
- for (let [index, elem] of ['a', 'b'].entries()) {
- console.log(index, elem);
- }
- // 0 "a"
- // 1 "b"
复制代码 遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。
在ES6中,有三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。
一个对象如果要有可被for...of循环调用的Iterator接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)。
并不是所有类似数组的对象都具有iterator接口,一个简便的解决方法,就是使用Array.from方法将其转为数组。- let arrayLike = { length: 2, 0: 'a', 1: 'b' };
- // 报错
- for (let x of arrayLike) {
- console.log(x);
- }
- // 正确
- for (let x of Array.from(arrayLike)) {
- console.log(x);
- }
复制代码
for...in循环依然可以用来遍历键名。
使用Object.keys方法将对象的键名生成一个数组,然后遍历这个数组。
- for (var key of Object.keys(someObject)) {
- console.log(key + ": " + someObject[key]);
- }
复制代码 与其他遍历语法的比较
以数组为例,JavaScript提供多种遍历语法。最原始的写法就是for循环。
for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]); } 这种写法比较麻烦,因此数组提供内置的forEach方法。
myArray.forEach(function (value) { console.log(value); }); 这种写法的问题在于,无法中途跳出forEach循环,break命令或return命令都不能奏效。
for...in循环可以遍历数组的键名。
for (var index in myArray) { console.log(myArray[index]); } for...in循环有几个缺点。
数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。 for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。 某些情况下,for...in循环会以任意顺序遍历键名。 总之,for...in循环主要是为遍历对象而设计的,不适用于遍历数组。
for...of循环相比上面几种做法,有一些显著的优点。
for (let value of myArray) { console.log(value); } 有着同for...in一样的简洁语法,但是没有for...in那些缺点。 不同用于forEach方法,它可以与break、continue和return配合使用。 提供了遍历所有数据结构的统一操作接口。 下面是一个使用break语句,跳出for...of循环的例子。
for (var n of fibonacci) { if (n > 1000) break; console.log(n); } 上面的例子,会输出斐波纳契数列小于等于1000的项。如果当前项大于1000,就会使用break语句跳出for...of循环。
|