缘,妙不可言——开始系统梳理es6后,发现关于循环的知识点又有了不少补充,正好填一下上次的坑嘛【抖】,本文有大量部分直接摘于es6标准入门
ps: 上集回顾
其实是es5引入的方法,返回一个数组,常用于与for-of搭配遍历,成员是**参数对象自身(不含继承)的所有可枚举(enumerable)**属性的键名:
let obj = { foo: 'bar', baz: 42 }
Object.keys(obj)
// ["foo", "baz"]
相比之下,我们更熟悉的for-in遍历虽然同样是遍历可枚举属性的键名,但是它遍历的范围不只是对象自身,还有它的原型链,相比之下object.keys()在大多情况下更加适用。
另外,es2017中有一个提案,引入Object.values和Object.entires与其配套使用:
let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
其实这才是重头戏啊,由于涉及到的点太多,只提及一点概念以及相关关键词。
Iterator 的作用有三个:
for...of
循环,Iterator接口主要供for...of
消费Iterator的遍历过程如下:
next
方法,可以将指针指向数据结构的第一个成员next
方法,指针就指向数据结构的第二个成员next
方法,直到它指向数据结构的结束位置每一次调用next
方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value
和done
两个属性的对象。其中,value
属性是当前成员的值,done
属性是一个布尔值,表示遍历是否结束。
模拟 next 方法返回值:
var it = makeIterator(['a', 'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{value: undefined, done: true};
}
};
}
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator
属性,或者说,一个数据结构只要具有Symbol.iterator
属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator
属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历。
而原生具有该借口的数据结构如下:
以数组为例:
let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();
iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }
一个对象如果要具备可被for...of
循环调用的 Iterator 接口,就必须在Symbol.iterator
的属性上部署遍历器生成方法(原型链上的对象具有该方法也可),这个操作骚方法就太多了,还是详看es6吧,其中最值得注意的骚操作就是Generator函数。
没了?没了。Iterator涉及到的点和用法在es6入门中整理的很好了,继续复制粘贴感觉也没有太大意义嗯——