面試時又被人問起 JS 的 Iterator 迭代器。查閱 MDN,得知
非標准。 Iterator 函數是一個 SpiderMonkey 專有特性,並且會在某一時刻被刪除。為將來使用的話,請考慮使用 for...of 循環和 迭代協議。
如果用此 API 那么遍歷對象還得想下面這樣,手動包上 Iterator 得到迭代器才能繼續往下操作。
var a = {
x: 10,
y: 20,
};
var iter = Iterator(a);
console.log(iter.next()); // ["x", 10]
console.log(iter.next()); // ["y", 20]
console.log(iter.next()); // throws StopIteration
但其實,ES 標准雖然沒有直接支持 Iterator API,但它通過了內建迭代器的方案。就是使用 Symbol.iterator,這是 ES6 引入的。我們可以用他來遍歷String,Array,Map,Set。
// Array
var arr = ['a', 'b', 'c', 'd', 'e'];
var eArr = arr[Symbol.iterator]();
console.log(eArr.next().value); // a
console.log(eArr.next().value); // b
console.log(eArr.next().value); // c
console.log(eArr.next().value); // d
console.log(eArr.next().value); // e
// Map
const map1 = new Map();
map1.set('0', 'foo');
map1.set(1, 'bar');
const iterator1 = map1[Symbol.iterator]();
for (let item of iterator1) {
console.log(item);
}
// expected output: Array ["0", "foo"]
// expected output: Array [1, "bar"]
那遍歷對象是更推薦使用 for...in 這是 ES5 引入的 API,他還有一個變種是 Object.key(obj).forEach(item => {});
,這也是筆者常用的遍歷對象的方法。自然還可以變種成下面的 for...of 於 key 的形式了。
var student={
name:'wujunchuan',
age:22,
locate:{
country:'china',
city:'xiamen',
school:'XMUT'
}
}
for(let key of Object.keys(student)){
//使用Object.keys()方法獲取對象key的數組
console.log(key+": "+student[key]);
}
或者使用 yeild 那樣的函數包裝。
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for (let [key, value] of entries(obj)) {
console.log(key, "->", value);
}
// a -> 1
// b -> 2
// c -> 3