浅谈js 迭代器 - Kaiqisan

js 迭代器

ヤッハロー、Kaiqisanすうう、一つふつうの学生プログラマである ,这里,终于。。终于要讲迭代的原理----迭代器了,这篇文章可能讲得不是很好,大家直接看代码就可以了。

Iterator,一个迭代器对象,能拥有迭代机制。它拥有方法next(),可迭代下一个成员,也拥有属性Symbol.toStringTag,在创建对象的默认字符串描述中使用的字符串值属性,它由该Object.prototype.toString()方法在内部访问。
一般使用迭代器的方法有 forEach() every() some() reduce() map() filter()

下面为打开迭代器的方法

let arr = [2, 2, 4, 8]
console.log(arr.entries())
console.log(arr.keys())
console.log(arr.values())

这三个方法都可以打开迭代器,下面以entries()方法为例。

let arr = [2, 4, 8, 16]
let a = arr.entries() // 获取迭代器iterator
console.log(a.next()); // 第一次迭代,返回 { value: [0: 2], done: false }
console.log(a.next()); // 第二次迭代,返回 { value: [1: 4], done: false }
console.log(a.next()); // 第三次迭代,返回 { value: [2: 8], done: false }
console.log(a.next()); // 第四次迭代,返回 { value: [3: 16], done: false }
console.log(a.next()); 
// 第五次迭代,此时迭代已经完成,不会再返回值,返回 { value: undefined, done: true }

迭代器迭代数组的时候,每一次迭代都获取其相应要获取的值,并实时反馈当前是否已经结束迭代。

下面为iterator的方法模拟。

function iterator(arr){
    let i = 0;
    return {
        next: function(){
            return i < arr.length ?
            { value: arr[i++], done: false }:
            { value: undefined, done: true }
        }
    }
}

这个迭代器设计一方面是为了实现for of 自动迭代,只要一个参数它部署了Symbol.iterator属性,就可以通过for of实现自动迭代。

let arr = [2, 4, 8, 16]
for (let [item, i] of arr.entries()) {
    console.log(item, i)
}
// 输出结果 
// 0 2
// 1 4
// 2 8
// 3 16
let arr = [2, 4, 8, 16]
for (let item of arr.values()) {
    console.log(item)
}
// 2
// 4
// 8
// 16

之前也还提到for of 无法遍历对象,就是因为对象内部没有自带的迭代器。为了实现对象的for of迭代,我们选择为它添加一个迭代器,这也是一个迭代器的工作原理

let obj = {
    name: 'kaiqisan',
    uid: 10001,
    sex: '男'
}
obj[Symbol.iterator] = function () {
    let keys = Object.keys(this) // 指向引用这个方法的对象obj
    let count = 0
    return {
        next() {
            if (count < keys.length) {
                return { value: obj[keys[count++]], done: false }
            } else {
                return { value: undefined, done: true }
            }
        }
    }
}
for (let item of obj) {
    console.log(item)
}
// kaiqisan
// 10001
// 男

但其实,说实在的,数组在本质上面其实就是对象,如果不信,请输入以下代码查看一下

console.log(typeof []); // object

数组这个“对象”,已经自动对成员分配键名,那就是它的下标,它还有length长度属性,当然,我们也可以自己添加属性值,也可以为其原型添加方法.

Array.prototype.getName = function() {
    console.log('ok')
}

又因为数组方便遍历,也又经常被遍历,所以它的原型拥有迭代器。

console.log([].__proto__); // 打开看看

总结

有时候,我们多逛逛底层,研究底层的原理,这样,我们才能对js有更加深刻的理解,其实不止js,学别的语言也应如此。就像是面试java岗的人经常被问到是否研究过spring的源码,面试官就是考察您的钻研能力与学习能力。嘛,为了找到工作,也为了提升自己,请务必多多研究底层原理,语言是一种工具,拆开查看内部构造能为日后更加得心应手打造一个良好的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kaiqisan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值