数组和字符串是最常用的迭代器对象,那么我们在这里说的迭代器是什么意思呢?简单来说,迭代器用于可迭代的对象,让其拥有一些令人赞叹的奇效,这么说有些空洞,让我们从代码来进入今天的话题:
let range = {
from: 1,
to: 5
};
// 我们希望 for..of 这样运行:
for(let num of range) // num=1,2,3,4,5
我们看看这个例子,似乎找不到解决的办法,如何让其中的数字循环输出呢?
这时就需要用到我们的迭代器,可是先别急,我们先看看使用迭代器的细节和要求:
1.当 for..of 循环启动时,它会调用这个方法(如果没找到,就会报错)。
这个方法必须返回一个 迭代器(iterator) —— 一个有 next 方法的对象。
从此开始,for..of 仅适用于这个被返回的对象。
2.当 for..of 循环希望取得下一个数值,它就调用这个对象的 next() 方法。
next() 方法返回的结果的格式必须是 { done: Boolean, value: any },
3.当 done = true 时,表示循环结束,否则 value 是下一个值。
当然,还是那句话,没有代码的解释都是空洞的,我们来看看代码:
let range = {
from: 1,
to: 5
};
//创建一个迭代器,在我们调用for of时使用
range[Symbol.iterator] = function () {
// 返回一个自己定义的对象,获取对应对象中的数据,next()函数也是返回中的一个对象
return {
current: this.from,
last: this.to,
next() {
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return {
done: true
}
}
}
}
}
我们来看这段代码:我们要使用迭代时首先就要申明一个迭代器,同时在添加一个next函数,而next函数中返回的就是上面提到的如果输出的数字小于此时的last就会导致current,从而实现我们的递增输出数字。
在了解了迭代器后,我们再介绍两个新的名词:可迭代(iterable)和类数组(array-like)
1.可迭代(iterable)是实现了Symbol.iterator 方法的对象。如上面的range对象
2.类数组(array-like)是有索引和length属性的对象看起来很像对象
注意: 字符串既是可迭代的又是类数组的。
可迭代对象和类数组对象通常都 不是数组,它们没有 push 和 pop 等方法。
如果我们有一个这样的对象,并想像数组那样操作它,那就非常不方便。
例如,我们想使用数组方法操作 range,应该如何实现呢?
这时就需要我们的有一个全局方法 Array.from 可以接受一个可迭代或类数组的值,并从中获取一个“真正的”数组。
然后我们就可以对其调用数组方法了,简单来说Array.from可以将类数组对象转换成另一个真正的数组
例如:
let arrayLike = {
0: "Hello",
1: "World",
length: 2
};
let arr = Array.from(arrayLike); // (*)
此时就可以对arr使用数组的方法
对于可迭代对象同样也是如此
let arr = Array.from(range);
alert(arr); // 1,2,3,4,5 (数组的 toString 转化方法生效)
这里介绍第二种将字符串转换成数组的方法
let str = "jshcks";
let char = Array.from(str);
此时的str就被转换成了数组,可以使用数组的方法
注意 Array.from()可以添加其他的参数,
Array.from(obj[, mapFn, thisArg])
let arr = Array.from(range, num => num * num);
alert(arr); // 1,4,9,16,25