前言
迭代器(Iterator),是 ES6 引入的一种新的遍历机制,这篇文章呢带大家详细了解一下ES6中的Iterator。
hasOwnProperty方法
这个方法是在对象的原型上,给实例对象用的,用来判断是否具有自己的属性。
我们具体来看一下是怎么用的,
for in 遍历对象或数组具有以下特点:
- 循环返回的是对象的键名
- 遍历数组返回的是下标
- 不仅可以遍历显示具有的属性,还可以遍历到对象原型上的属性
大家看第三点,怎样让它遍历不到对象原型上的属性呢,因为大多数时候我们不需要原型上的属性。这就可以用hasOwnProperty方法来解决。
let obj = {
a: 1
}
let obj2 = Object.create(obj)
obj2.aa = 100
obj2.bb = 200
let res = []
for (let key in obj2) {
// 判断该key是否为obj2显示具有的属性
if (obj2.hasOwnProperty(key)) {
res.push(obj2[key])
}
}
console.log(res);
上述代码结果为[100,200],这样就遍历不到原型上的属性了。如果遍历数组的话,虽然数组原型上不具有此方法,但是数组也是对象创建的,也可以继承到此方法。
一些数组身上的遍历方法
for循环
for (let i = 0; i < arr.length; i++) {}
forEach
arr.forEach((item, index, arr) => {})
map
arr.map((item, index, arr) => { return XXX })
reduce
let sum = arr.reduce((pre, item, inde, arr) => { return pre + item }, 0)
filter
arr.filter((item, index, arr) => { return item > 2 })
(把满足条件的过滤出来,有返回值,返回值为数组)
ES6新增的遍历数组方法(for of)
用for of遍历有以下特点:
- 遍历数组返回的是元素
- 不能遍历不具有
iterator属性的数据结构 - 不能遍历到数组原型上的属性
Array.prototype.d = 'd'
const arr = [1, 2, 3, 4]
for (let item of arr) { // obj is not iterable
console.log(item);
}
结果为:1 2 3 4
接下来就深入了解一下Iterator。
Iterator
概念
迭代器(Iterator)是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator的方法来实现。
原理
通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置;随后通过 next 方法进行向下迭代指向下一个位置,next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性,value 是当前属性的值,done 用于判断是否遍历结束;当 done 为 true 时则遍历结束。
应用
问题:用迭代器遍历数组,让数组的每一项都乘2。
let arr = [1, 2, 3]
function each(arr) {
let res = []
let it = arr[Symbol.iterator]()
function deep() {
let current = it.next()
//遍历完毕退出
if (current.done) {
return
}
res.push(current.value * 2)
//递归
deep()
}
deep()
return res
}
let newArr = each(arr) // [2, 4, 6]
console.log(newArr);
结果为:[2,4,6]
实现(面试考点)
面试官问:你能不能实现让下面的代码a的值为1,b的值为2?
let [a, b] = { a: 1, b: 2 }
console.log(a, b);
首先,我们应该想着让{ a: 1, b: 2 } 这个对象具有可迭代属性;在对象原型上挂上[Symbol.iterator],返回出一个数组[1,2]。对象身上有个方法Object.values(obj)可以以数组的形式返回出键值,得到数组就可以用[Symbol.iterator]了。
Object.prototype[Symbol.iterator] = function () {
// 返回一个 Array 类型的可迭代对象
return Object.values(this)[Symbol.iterator]()
}
let [a, b] = { a: 1, b: 2 } // [1, 2]
console.log(a, b);
这样就不报错了。
结语
迭代器(Iterator)在我们日常开发过程中用得比较少,但是了解此原理对我们学习是有帮助的,这也是面试的常考点。