广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript详解类数组与可迭代对象的实现原理
  • 506
分享到

JavaScript详解类数组与可迭代对象的实现原理

2024-04-02 19:04:59 506人浏览 薄情痞子
摘要

目录可迭代对象(Iterable object)Symbol.iterator把对象本身构造成迭代器String也是可迭代的String的迭代器类数组对象和可迭代对象Array.fr

可迭代对象(Iterable object)

数组是一个特殊的对象,它和普通对象的区别不仅仅在于元素的顺序访问、存储。另外一个重要的区别是:数组是可迭代的,也就是可以使用for ... of语句访问(迭代)所有的元素。

我们可以简单的做一个小实验:

let arr = [1,2,3,4,5]
for(let val of arr){
    console.log(val)
}

代码执行结果:

以上代码就简单的使用了数组的迭代特性,我们在访问数组元素的时候,不必使用元素的下标。

如果我们对一个普通对象使用for ... of语句会发生什么呢?

let obj = {
    name:'xiaoming',
    age:12,
}
for(let para of obj){ //代码会报错
    console.log(para)
}

执行效果如下:

这就证明普通的对象和数组之间还有一个可迭代的差距,我们称具备迭代功能的对象为可迭代对象。

Symbol.iterator

如果我们希望一个对象可以迭代,必须为对象添加一个名为Symbol.iterator的方法(一个专门使对象可迭代的内建Symbol)。

方法作用包括:

  • 当使用for ... of循环迭代对象时,就会调用Symbol.iterator方法,这个方法必须返回一个迭代器(一个有next()方法的对象)。
  • 得到迭代器后,for ... of会不断的调用迭代器的next()方法获得下一个元素
  • next()方法返回的内容必须符合格式:{done:Boolean,value:any},当done:true时,循环结束,否则value就是下一个值。

迭代器:

迭代器是借鉴c++等语言的概念,迭代器的原理就像指针一样,它指向数据集合中的某个元素,你可以获取它指向的元素,也可以移动它以获取其它元素。迭代器类似于数组中下标的拓展,各种数据结构,如链表List)、集合(Set)、映射(Map)都有与之对应的迭代器。

js中的迭代器是专门为了遍历这一操作设计的。每次获取到的迭代器总是初始指向第一个元素,并且迭代器只有next()一种行为,直到获取到数据集的最后一个元素。我们无法灵活移动迭代器的位置,所以,迭代器的任务,是按某种次序遍历数据集中的元素。

可迭代对象

实现一个可迭代对象:

let obj = {
    from:1,
    to:5,
}
obj[Symbol.iterator] = function(){
    //返回一个迭代器
    return {
        current:this.from,
        last:this.to,
        next(){
            if(this.current<this.last){
                return {done:false,value:this.current++}
            }else{
                return {done:true}//迭代结束
            }
        }
    }
}
for(let para of obj){
    console.log(para)
}

代码执行效果:

注意,以上对象虽然可以进行迭代了,但是,迭代使用使用的材料并非对象,而是Symbol.iterator返回的迭代器(也是一个对象)。

把对象本身构造成迭代器

以上代码构造了一个内建函数Symbol.iterator(),这个函数返回了一个迭代器对象。我们还可以采用另外一种实现迭代器的方式:把对象本身做成迭代器:

let obj = {
    from:1,
    to:5,
    [Symbol.iterator](){
        this.current = this.from;
        return this;//返回对象本身
    },
    next(){//给对象添加一个next方法
        if(this.current<this.to){
            return {done:false,value:this.current++}
        }else{
            return {done:true}
        }
    }
}
for(let para of obj){
    console.log(para)
}

代码执行效果和上面的图片展示相同。

这么做虽然代码更加简洁了,但是由于并没有新的可迭代对象产生,我们就没有办法同时执行两个for ... of循环迭代同一个对象了,但是两个并行的迭代在同一个对象上是非常罕见的。

我们可以总结可迭代对象的概念:

所谓可迭代对象,就是比普通对象多了一个名为Symbol.iterator方法的普通对象,这个方法返回一个迭代器。

或者,一个具备Symbol.iterator同时具备next方法的对象也是一个可迭代的对象。

String也是可迭代的

数组和字符串都是可以迭代的,我们可以很方便的使用for...of语句迭代数组中的字符元素:

let str = '123'
for(let c of str){
    console.log(c)
}

这对于代理对(UTF-16扩展字符)同样是有效的:

let str = '??????❤????'
for(let c of str){
    console.log(c)
}

执行效果如下:

String的迭代器

并非只有for...of语句能够使用迭代器,我们还可以显式的调用迭代器:

let str = '12345'
let itr = str[Symbol.iterator]()
while(true){
    let result = itr.next()
    if(result.done)break;
    console.log(result.value)
}

代码执行效果:

以上代码执行了遍历字符串字符的操作,是不是觉得可迭代对象就没有这么神秘了!

类数组对象和可迭代对象

类数组和可迭代在遍历功能上非常相似,都可以方便的方式内部元素,但是二者仍然有明显的区别:

  • iterable可迭代对象:实现了Symbol.iterator的对象;
  • array-like类数组对象:具有数字索引,并且有length属性;

字符串就是一个即使类数组又是可迭代的对象。

可迭代和类数组对象通常都不是数组,如果我们想把一个可迭代或者类数组对象转为数组,需要使用Array.from方法。

Array.from

使用Array.from将字符串转为数组:

let str = '123'
let arr = Array.from(str)
console.log(arr)

代码执行效果如下:

把自定义的类数组对象转为数组:

let obj = {
    0:'0',
    1:'1',
    2:'2',
    length:3
}
let arr = Array.from(obj)
console.log(arr)

代码执行结果:

Array.from的完整语法:

Array.from(obj[, mapFunc, thisArg])

mapFunc方法会在生成数组之前对每个可迭代或类数组元素调用,如果mapFunc是一个成员方法,可以使用thisArg提供this指针。

举个例子:

let str = '12345'
let arr = Array.from(str,itm=>+itm)
console.log(arr)

代码执行结果:

这里通过映射函数,将本应该生成字符数组转为数字数组。

总结

  • 可以使用for...of语法的对象被称为可迭代对象
  • 可迭代对象是在普通对象的基础上实现了Symbol.iterator方法的对象
  • Symbol.iterator方法返回了一个迭代器;
  • 迭代器包含一个next方法,该方法返回下一个元素的值;
  • next方法返回值需要满足格式{done:Boolean,value:nextVal},当done:true时,迭代结束
  • Array.from可以把类数组和可迭代对象转为数组;

到此这篇关于javascript详解类数组与可迭代对象的实现原理的文章就介绍到这了,更多相关JavaScript 类数组与可迭代对象内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript详解类数组与可迭代对象的实现原理

本文链接: https://www.lsjlt.com/news/150975.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript详解类数组与可迭代对象的实现原理
    目录可迭代对象(Iterable object)Symbol.iterator把对象本身构造成迭代器String也是可迭代的String的迭代器类数组对象和可迭代对象Array.fr...
    99+
    2022-11-13
  • JavaScript类数组和可迭代对象如何实现
    本篇内容介绍了“JavaScript类数组和可迭代对象如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2022-10-19
  • JavaScript数组及非数组对象的深浅克隆详解原理
    目录什么是浅克隆、深克隆1.对数组进行克隆1.1 浅克隆1.2 深克隆2.对非数组对象进行克隆2.1 浅克隆2.2 深克隆3.整合深克隆函数什么是浅克隆、深克隆 浅克隆:直接将存储在...
    99+
    2022-11-12
  • TypeScript数组实现栈与对象实现栈的区别详解
    目录前言数组实现栈实现思路实现代码编写测试代码对象实现栈实现代码编写测试代码二者的区别十进制转二进制前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时...
    99+
    2022-11-13
  • 详解Java面向对象之多态的原理与实现
    目录何为多态代码实现多态理解何为多态 定义: 多态是指不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式。系统在运行时(而非编译时),...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作