目录
1. 操作与数据类型
2.迭代器
3. 实现迭代器接口
1. 操作与数据类型
四个操作与五种数据类型的关系:(直接使用)
string | array | object | map | set | |
for...in | 行 | 行 | 行 | 不行 | 不行 |
forEach | 不行 | 行 | 不行 | 行 | 行 |
for...of | 行 | 行 | 不行 | 行 | 行 |
... (扩展运算符) | 行 | 行 | 不行 | 行 | 行 |
其中有几点你需要知道:
- for in遍历键(索引),for of遍历值(必须是可迭代对象,遍历的是什么也可以自己手动修改),forEach可以传入的方法接收值、键、只读的传入数据类型三个参数。
- for of与...扩展运算符能调用都是因为他们实现了Symbol.interator接口!所以理论上任何数据类型都可以使用他们,只要实现了Symbol.interator接口。
- string类型也实现了Symbol.interator接口,只不过是实现在包装类型String上,我们可以通过new String()来创造一个包装类型的对象,然后就能看到Symbol.interator的具体实现了。
- object使用for in时,不会遍历symbol类型的键。
- object可以在新建对象时使用扩展运算符!如const obj1 = { a:1, ...obj }
2.迭代器
迭代器是es6新增加的功能,以满足各种数据类型的迭代需要,es6本身就实现了许多数据类型的迭代器:
1. Array
2. string(实现在包装类String上,可以使用String()手动创造包装类对象)
3. Set
4. Map
5. arguments对象
6. NodeList等DOM集合类型
这也就代表了,我们不用任何操作,就可以使用for of和...对它们进行操作。
需要注意,在一个函数中,我们可以通过arguments和...params(变量名可以自定义)一次性接收不限数量的参数,而且它们都可以使用for of与...扩展运算符,但是他们是不同的!arguments是一个伪数组,而params是真真正正的数组。
比如如下代码:
function f(...params){
console.log(params)
console.log(arguments)
}
f(1,2,3)
输出值如下:
我们可以看到它们是有些不同点的,我们可以如此理解:
- 使用...运算符的params变量是一个数组,它的原型是Array,我们能够进行迭代的原因是Array原型上面实现了Symbol.interator接口。
- arguments变量不是一个数组(只是一个伪数组),它的原型是Object,我们能够进行迭代的原因是arguments本身就实现了Symbol.interator接口,即arguments[Symbol.interator]。
因此,如果你希望使用真数组,那么使用...params接收参数将会是不错的选择;但是,如果你在某些情况下不得不使用arguments这个伪数组,你可以使用const arr = [ ...arguments ]来将伪数组转换为真数组!事实上,任何可迭代的数据类型都可以这样转换。
需要注意,es6的箭头函数不能使用arguments,只能使用...扩展运算符!
3. 实现迭代器接口
接下来我们来手动实现一个简易的迭代器接口
以下仅是示例,不推荐真的对原始值的包装类型进行修改!一般在自己定义的对象或者类上面进行如下操作!
今天,程序员小A想:我想执行一个语句块50次,一般使用for(let i = 0;i < 50;i++) { ... },能不能有更简便的写法,以达到相同的效果呢?比如使用for of这种语法,一个for(const i of 50) { ... } 不就解决问题了吗?
他写下了如下代码:
for(const i of 5){
console.log(i)
}
但是,他发现浏览器报了这个错误!
“5是不可迭代的”,那我们就手动让它可迭代!
Number.prototype[Symbol.iterator] = function(){
const max = this.valueOf()
let count = 0
return {
next(){
if(count < max){
return {done:false , value:count++}
} else {
return {done:true , value:undefined}
}
}
}
}
for(const i of 5){
console.log(i)
}
可以看到,达到了他想要的效果!
同样的,...扩展运算符也可以使用了!
console.log(...50)
这样我们就成功的手动实现了迭代器接口!