@Dale-Lin
2019-09-27T15:02:06.000000Z
字数 2480
阅读 711
深入理解ES6
迭代器是一中特殊对象,专为迭代过程设计有专有API,所有迭代器都有一个 next() 方法,每次调用都返回一个结果对象。
结果对象有两个属性——value
, done
,分别表示返回的值和是否完成。
生成器用来返回一个迭代器:
function *createIterator(items) {
for (let i = 0; i < items.length; i++) {
yield items[i];
}
return 'Done!';
}
let iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); //"{value: 1, done: false}"
console.log(iterator.next()); //"{value: 2, done: false}"
console.log(iterator.next()); //"{value: 3, done: false}"
// 最后返回函数返回值
console.log(iterator.next()); //"{value: 'Done!', done: true}"
// 之后所有调用都会返回 undefined
console.log(iterator.next()); //"{value: undefied, done: true}"
在 function
关键字后用 *
表示它是一个生成器;yield
关键字用来指定调用迭代器的 next()
方法时的返回值和返回顺序。
每当执行完一条 yield
语句就会停止,直到下次调用 next()
方法继续。
yield 关键字只能在生成器内部使用,就像一个 return 关键字一样,不能穿透函数边界。
有以下生成器表达式语法:
let createIterator = function *(items) {
//code
}
let o = {
*createIterator(items) {
//code
}
}
let iterator = o.createIterator([1, 2, 3]);
yield*
语句表明后面是一个可迭代对象,也可以是另一个生成器:
function* g4() {
yield* [1,2,3]
return 'foo'
}
var result
function* g5() {
result = yield* g4()
}
var iterator = g5()
数组、Set、Map、字符串是可迭代对象,具有 Symbol.iterator
方法,可以使用 for-of 循环。
for-of 循环每执行一次都会调用可迭代对象的 next()
方法,并将迭代器返回的结果对象的 value
属性储存在一个变量中,循环将持续执行到返回兑现的 done
属性值为 true
。
let values = [1, 2, 3];
//调用可迭代对象的 Symbol.iterator 方法返回默认迭代器
let iterator = values[Symbol.iterator]();
console.log(iterator.next()); //"{value: 1, done: false}"
console.log(iterator.next()); //"{value: 2, done: false}"
console.log(iterator.next()); //"{value: 3, done: false}"
console.log(iterator.next()); //"{value: undefined, done: true}"
默认情况下,开发者定义的对象都不是可迭代对象,但如果给 Symbol.iterator
属性添加一个生成器函数,则可将其变成可迭代对象(可使用 for-of):
const collection = {
items: [],
*[Symbol.iterator]() {
for (let item of this.items) {
yield item;
}
}
};
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for (let x of collection) {
console.log(x);
}
//1
//2
//3
返回一个对象的可枚举属性的键名组成的数组:
let b = {
name: 'Nicholas',
age: 10,
};
Object.keys(b); // ['name', 'age']
返回一个对象的可枚举属性的值组成的数组:
let b = {
name: 'Nicholas',
age: 10,
};
Object.values(b); // ['Nicholas', 20]
返回由一个对象的可枚举属性的键值对数组所组成的数组:
let b = {
name: 'Nicholas',
age: 10,
};
Object.entries(b); // [['name', 'Nicholas'], ['age', 10]]
使用
new Map(Object.entries(obj))
可以快速将 Object 转化成 Map。
反操作,将一个键值对对象(entries 数组或map)转化为对象:
const map = new Map([['foo', 'bar'], ['baz', 10]]);
const obj = Object.fromEntries(map);
// {foo: 'bar', baz: 10}
每个集合类型都有一个默认的迭代器,在 for-of 循环中,如果没有显式指定,则使用默认的迭代器。
数组和 Set 集合默认迭代器是 values(),Map 集合则是 entries()。
在 entries() 返回的数组键值对中可以使用解构。
使用 for-of 循环优化字符串的迭代,以全面支持 Unicode。
迭代 NodeList 也可以使用 for-of 循环,其行为和数组的默认迭代器完全一样。