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

本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于类数组和可迭代对象的实现原理,包括了把对象本身构造成迭代器、string的迭代器等等相关内容,下面一起来看一下吧,希望对大家有帮助。

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

【相关推荐:javascript视频教程、web前端】

可迭代对象(Iterable object)

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

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

立即学习“Java免费学习笔记(深入)”;

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

登录后复制

代码执行结果:

image-20220604080921048

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

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

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

登录后复制

执行效果如下:

image-20220604081556714

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

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)}

登录后复制

代码执行效果:

image-20220604083540285

注意,以上对象虽然可以进行迭代了,但是,迭代使用使用的材料并非对象,而是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)}

登录后复制

执行效果如下:

image-20220604085545804

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)}

登录后复制

代码执行效果:

image-20220604085813686

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

类数组对象和可迭代对象

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

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

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

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

Array.from

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

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

登录后复制

代码执行效果如下:

image-20220604091552590

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

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

登录后复制

代码执行结果:

image-20220604091736400

Array.from的完整语法:

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

登录后复制

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

举个例子:

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

登录后复制

代码执行结果:

image-20220604092137378

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

总结

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

Array.from可以把类数组和可迭代对象转为数组;

【相关推荐:javascript视频教程、web前端】

以上就是JavaScript类数组和可迭代对象的实现原理详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2700830.html

(0)
上一篇 2025年3月7日 19:10:24
下一篇 2025年3月2日 00:16:36

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 一文搞定JavaScript的节点操作

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于节点操作的相关问题,包括了父级节点、子节点、兄弟节点、增加删除复制节点等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web…

    2025年3月7日 编程技术
    200
  • 11个可以提升效率的chrome调试技巧

    本篇文章给大家分享11个chrome高级调试技巧,学会效率直接提升666%,希望对小伙伴们有帮助! chrome浏览器作为前端童鞋的老婆,相信你一定不陌生。调页面、写BUG、画样式、看php片少了它整个世界都不香了。 不信?一起来看看我们的…

    2025年3月7日 编程技术
    200
  • 简单了解JavaScript数据结构与算法之栈

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于栈的相关问题,包括了面向过程方法源码编写栈以及用面向对象的方法来源码书写等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、we…

    2025年3月7日
    200
  • JavaScript迭代器知识点总结

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于迭代器的相关问题,迭代就是指可以从一个数据集中按照一定的顺序,不断取出数据的过程,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、we…

    2025年3月7日 编程技术
    200
  • 深入聊聊JavaScript

    本篇文章给大家带来了关于javascript的相关知识,其中主要包括了为什么需要javascript引擎、浏览器内核与js引擎的关系、环境变量与记录等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、w…

    2025年3月7日
    200
  • 一篇搞定JavaScript DOM详细操作

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于dom详细操作的相关问题,包括了什么是dom、什么是dom tree、怎么获取dom等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视…

    2025年3月7日 编程技术
    200
  • JavaScript弱映射与弱集合知识详解

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于弱映射与弱集合的相关问题,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 简单来讲,如果一个变量、对象是“不可达”的,那…

    2025年3月7日
    200
  • 一文搞定JavaScript字符串对象基本知识

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于字符串对象的相关问题,包括了一些基本概念和实际使用等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 基本概念 基…

    2025年3月7日
    200
  • JavaScript对象和数组的解构赋值基础详解

    本篇文章给大家带来了关于javascript的相关知识,其中主要整理了对象和数组的解构赋值的相关问题,包括了数组解构、对象解构以及函数参数解析等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前…

    2025年3月7日 编程技术
    200
  • 简单聊聊JavaScript中的事件监听

    本篇文章给大家带来了关于javascript的相关知识,其中主要整理了事件监听的相关问题,包括了什么是事件监听、设置事件监听的方法等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 什么是…

    2025年3月7日
    200

发表回复

登录后才能评论