请问以下JS代码的执行结果是什么?
function control(x) {
if (x == 3) throw new Error("break");
}
function foo(x = 6) {
return {
next: () => {
control(x);
return {done: !x, value: x && x--};
}
}
}
let x = new Object;
x[Symbol.iterator] = foo;
for (let i of x) console.log(i);
6、5、4、报错
对象x的操作其实是为了让x可以被函数foo通过for of遍历到每一个值,同时因为初始值是6所以是递减的结果,control只是做一个中断操作。
1、什么是迭代器?
迭代器是一个对象,需要满足:对象内部有方法next,next方法要求返回对象{done: true或false, value:值 }
!!!(注意区分:迭代器 和可迭代对象 是不一样的)
2、一个迭代器是如何遍历的?
const arr = ["a","b"]
// 数组默认是一个可迭代对象,就好比题目中的对象x
const iterator = arrSymbol.iterator // 拿到迭代器
console.log(iterator.next());
console.log(iterator.next());
// { value: 'a', done: false }
// { value: 'b', done: false }
// { value: undefined, done: true }
不难看出,value表示每次遍历的值,而done表示遍历是否完成。
3、for...of...补充
for... of...的使用需要是一个可迭代对象,这道题的x,也是因为是一个可迭代对象,所以才可以用的for...of
可以理解为:for..of..就是上面调用iterator.next()的语法糖,直到最后done为true表示遍历完了。...
4、什么是可迭代对象?
如果一个对象,实现了[Symbol.iterator]方法,且这个方法返回一个迭代器(这个方法就是一个生成迭代器的函数,比如题目中的foo函数)
function foo(x = 6) {
return { // 返回一个迭代器
next: () => {
control(x);
return {done: !x, value: x&&x-- };
}
}
}
// x成为可迭代对象
x[Symbol.iterator] = foo
5、得结果
for(let i of x) console.log(i);
既然x是可迭代对象,那他可以用for...of...进行遍历,遍历时会自动去执行foo,foo返回迭代器。
上面也说了for...of...的遍历就是:一次次的调用iterator的next,拿到value,直到next返回的done为true。
function foo(x = 6) {
return {
next: () => {
control(x);
return {done: !x, value: x && x--};
}
}
}
里层next函数调用的x是foo的参数x(闭包),x默认赋值为6,通过题目中的control函数可以知道,x=3的时候,就抛错,结束了。
当x=6,return{ done:!x, value: x && x--}
done为false,value是x && x--
6 && 6, &&前者为true,value结果取后者,return { done:false, value : 6},
然后x--变成5
继续。。。。最后结果
6,5,4,抛错
-
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。至于属性名Symbol.iterator,它是一个表达式,返回Symbol对象的iterator属性,这是一个预定义好的、类型为 Symbol 的特殊值,所以要放在方括号内 2. throw 异常信息;中止程序抛出异常,可用于中止程序
-
foo 是遍历器生成函数,遍历的时候遇到 throw 就中止遍历和抛出错误
-
还是推荐 阮一峰老师 https://es6.ruanyifeng.com/#docs/iterator