我之前学到了对象与数组进行拼接,如果对象不加 [Symbol.isConcatSpreadable]:true,对象不会当作数组处理,反之,对象的元素将会像数组中的元素一样,被复制进数组中。
对数组的泛化,几乎所有对象可以作为在for…of 循环中的对象。
可迭代对象必须有迭代器 iterator
迭代器中必须有next()方法
构造迭代器的实例:
我们有range 对象,但当前没有迭代器
let range = {
from:1,
to:5
}
我们需要为range 添加迭代器,使之成为可迭代对象,这样就可以应用for…of 循环
let range ={
from:0;
to:5;
}
// 运行for...of时吗,首先执行的就是Symbol.iterator
range[Symbol.iterator] = function() {
return {
// 返回当前元素,和目标元素
current:this.from,
last:this.to, // 当last = infinity 时,迭代器将永远执行下去,我们可以使用break跳出循环
// 必须有next方法,迭代器才能继续下去
next(){
// done 为true 时迭代结束
if (this.current <= this.last){
return {
done:flase,value:this.current++};
else return {
done:true};
}
}
}
}
迭代器的另一种写法,在对象声明时。
let range = {
from:0,
to:5,
[Symbol.iterator](){
this.current = this.from;
return this;
},
next(){
if ( this.current <= this.to ){
return {
done:false,value:this.current++};
}
else return {
done:false};
}
}
let str = "Hello World"
let iterator = str[Symbol.iterator](); //返回一个迭代器
while(true){
let result = iterator();//result = {done:bool,value:any}
if ( result.done ) break;
alert(result.value);
}
完成了对象的迭代器声明,此时的对象就是可迭代对象了。我们可以使用for…of对我们的可迭代对象进行迭代操作。
定义:有index和length属性,但可能没有原生数组的其他方法,所以只是 array-like 类数组。
类数组对象和可迭代对象的相似点:都可以进行迭代操作。如字符串就是类数组对象,当然数组也可以进行迭代操作。
let str = "i love u"
for (let i of str){
console.log(i);// i l o v e u
}
使用Array.from() 我们可以对可迭代对象和类数组对象进行数组化,进行数组化后就可以使用原生数组的方法进行操作。
let str = "i love u" // 字符串对象是类数组的也是可迭代的
let arrayStr = Array.from(str);
console.log(arrayStr.slice(0,3));// i l
原生方法可能不支持UTF-16,会出现乱码
我们对原生的数组方法进行修改,使之可以对UTF-16 字符进行处理
// 这里参数为UTF-16字符串(类数组对象)
function slice(arrLike,start,end){
return Array.from(arrLike).slice(start,end).join('');
}
mapFn:一个函数,在进行数组化的时候对每一个元素进行函数内的操作
thisArg:this对象
多数内建方法的处理对象都是可迭代对象或者类数组对象,而不是“真正的”数组,这样抽象度更高。