当前位置: 首页 > news >正文

网站访客记录打开有些网站显示建设中

网站访客记录,打开有些网站显示建设中,深圳企业做网站,建网站要多少钱用自己的服务器在 JavaScript 中,“可迭代对象”(Iterable Object)是一个贯穿 ES6 及后续版本的重要概念,它为统一数据遍历方式、简化集合操作提供了核心支撑。无论是日常开发中常用的for...of循环,还是数组的map、filter方法&#x…

在 JavaScript 中,“可迭代对象”(Iterable Object)是一个贯穿 ES6 及后续版本的重要概念,它为统一数据遍历方式、简化集合操作提供了核心支撑。无论是日常开发中常用的for...of循环,还是数组的mapfilter方法,亦或是展开运算符(...),其底层都依赖于可迭代对象的规范。本文将从概念定义、核心机制、实践场景到常见误区,全方位拆解可迭代对象的细节,帮你彻底掌握这一知识点。

一、什么是可迭代对象?核心定义与判定标准

1. 官方定义

根据 ECMAScript 规范,可迭代对象是指部署了[Symbol.iterator]方法的对象。这里的[Symbol.iterator]是一个特殊的内置 Symbol 值,它指向一个 “迭代器生成函数”—— 调用该函数时,会返回一个符合 “迭代器协议”(Iterator Protocol)的对象(即迭代器)。

简单来说,可迭代对象的本质是 “能产生迭代器的对象”,而迭代器则负责提供 “依次访问数据” 的能力。

2. 判定可迭代对象的 2 个关键条件

一个对象要成为可迭代对象,必须满足以下两点:

  • 条件 1:对象自身或其原型链上存在[Symbol.iterator]属性(注意:Symbol.iterator是 Symbol 类型,不能通过字符串字面量访问);

  • 条件 2[Symbol.iterator]属性的值是一个无参数函数,且该函数返回的迭代器对象必须包含next()方法。

3. 原生可迭代对象有哪些?

JS 内置了多种可迭代对象,无需手动部署[Symbol.iterator]即可直接使用,常见的包括:

  • 数组(Array):[1, 2, 3]

  • 字符串(String):"hello"(遍历的是字符)

  • 集合类型:SetMap

  • 类数组对象:argumentsNodeList(如document.querySelectorAll('div')的返回值)

二、深入可迭代对象的核心:迭代器协议

可迭代对象的核心能力依赖于 “迭代器”,而迭代器必须遵守迭代器协议—— 即包含一个next()方法,且该方法返回一个具有valuedone两个属性的对象:

  • value:当前迭代的值(若donetrue,则value可省略,通常为undefined);

  • done:布尔值,标识迭代是否结束(true表示迭代完成,false表示仍有后续值)。

实例:手动调用迭代器的next()方法

以数组(原生可迭代对象)为例,我们可以手动获取其迭代器并调用next(),观察迭代过程:

const arr = [10, 20, 30];// 1. 获取迭代器:调用数组的[Symbol.iterator]()方法const iterator = arr[Symbol.iterator]();// 2. 手动调用next(),依次获取迭代结果console.log(iterator.next()); // { value: 10, done: false }console.log(iterator.next()); // { value: 20, done: false }console.log(iterator.next()); // { value: 30, done: false }console.log(iterator.next()); // { value: undefined, done: true }// 后续再调用next(),始终返回{ value: undefined, done: true }console.log(iterator.next()); // { value: undefined, done: true }

从结果可见:迭代器是 “一次性” 的,一旦done变为true,后续调用next()不会再产生新的value

三、实践:手动实现一个可迭代对象

原生可迭代对象虽方便,但实际开发中可能需要自定义集合(如 “链表”“队列”),此时需手动部署[Symbol.iterator]方法,让自定义对象成为可迭代对象。

案例:自定义 “数字范围” 可迭代对象

需求:创建一个NumberRange类,实例化时传入startend,支持通过for...of遍历从startend的所有整数。

实现步骤:
  1. 定义NumberRange类,在构造函数中存储startend

  2. 为类部署[Symbol.iterator]方法,返回一个符合迭代器协议的对象(包含next()方法);

  3. next()方法中,控制valuestart递增到end,并在达到end后将done设为true

完整代码:
class NumberRange {constructor(start, end) {this.start = start;this.end = end;}// 部署[Symbol.iterator]方法,使其成为可迭代对象[Symbol.iterator]() {// 注意:用局部变量current存储当前迭代位置,避免使用this导致的状态污染let current = this.start;const end = this.end;// 返回迭代器对象(包含next()方法)return {next() {// 逻辑:若current <= end,返回当前值并递增;否则结束迭代if (current <= end) {return { value: current++, done: false };} else {return { done: true }; // value可省略}}};}}// 测试:使用for...of遍历自定义可迭代对象const range = new NumberRange(2, 5);for (const num of range) {console.log(num); // 输出:2、3、4、5}// 支持展开运算符(因展开运算符依赖可迭代协议)const arrFromRange = [...range];console.log(arrFromRange); // [2, 3, 4, 5]// 支持数组解构(同样依赖可迭代协议)const [a, b, c] = range;console.log(a, b, c); // 2 3 4
关键细节:
  • 迭代器的状态(current)需用局部变量存储,而非this.current—— 若用this,多个迭代器会共享同一状态,导致遍历混乱(例如同时创建两个迭代器,会互相干扰);

  • [Symbol.iterator]方法每次调用都会返回一个新的迭代器,确保每次遍历都是独立的(如上述代码中,多次for...of遍历range,都会从2开始)。

四、可迭代对象的典型应用场景

可迭代对象的价值在于 “统一遍历接口”,以下是其最常见的应用场景:

1. for...of循环

for...of是专门为可迭代对象设计的遍历语法,相比for循环更简洁,相比forEach更灵活(支持breakcontinue):

// 遍历字符串(可迭代对象)for (const char of "abc") {console.log(char); // a、b、c}// 遍历Set(可迭代对象)const set = new Set([1, 2, 2, 3]);for (const val of set) {console.log(val); // 1、2、3(自动去重)}// 遍历Map(可迭代对象,遍历的是[key, value]数组)const map = new Map([["name", "Tom"], ["age", 18]]);for (const [key, value] of map) {console.log(`${key}: ${value}`); // name: Tom、age: 18}

2. 展开运算符(...

展开运算符可将可迭代对象的元素 “展开” 为单个值,常用于数组拼接、对象初始化等场景:

// 展开数组const arr1 = [1, 2];const arr2 = [...arr1, 3, 4]; // [1, 2, 3, 4]// 展开字符串const str = "hello";const strArr = [...str]; // ["h", "e", "l", "l", "o"]// 展开Setconst set = new Set([5, 6]);const setArr = [...set]; // [5, 6]

3. 数组解构赋值

数组解构的底层依赖可迭代协议,因此可迭代对象都支持解构:

// 解构数组const [x, y] = [10, 20]; // x=10, y=20// 解构字符串const [a, b] = "ab"; // a="a", b="b"// 解构自定义可迭代对象(如前文的NumberRange)const range = new NumberRange(1, 3);const [first, second] = range; // first=1, second=2

4. 作为数组构造函数的参数

Array.from()方法可将可迭代对象转换为数组,这是处理非数组可迭代对象(如NodeList)的常用技巧:

// 将NodeList(可迭代对象)转换为数组const divs = document.querySelectorAll('div'); // NodeListconst divArr = Array.from(divs); // 数组,可使用数组的所有方法(如map、filter)// 将Set(可迭代对象)转换为数组const set = new Set([1, 2, 3]);const setArr = Array.from(set); // [1, 2, 3]

五、常见误区与注意事项

1. 误区 1:“类数组对象一定是可迭代对象”

类数组对象(如{ 0: "a", 1: "b", length: 2 })虽具有length属性和索引,但默认不是可迭代对象—— 因为其原型链上没有[Symbol.iterator]方法。

例如:

// 类数组对象(无[Symbol.iterator])const likeArr = { 0: "a", 1: "b", length: 2 };// 错误:likeArr不是可迭代对象,无法用for...of遍历for (const val of likeArr) {console.log(val); // Uncaught TypeError: likeArr is not iterable}// 解决:手动部署[Symbol.iterator],或用Array.from()转换为数组likeArr[Symbol.iterator] = Array.prototype[Symbol.iterator];for (const val of likeArr) {console.log(val); // a、b(正常遍历)}

2. 误区 2:“迭代器一定是对象”

迭代器通常是对象,但也可以是 “可调用的对象”(如函数)—— 只要满足 “包含next()方法” 的协议即可。不过这种情况极少用,日常开发中仍以对象形式的迭代器为主。

3. 注意:迭代器的 “一次性” 与 “状态性”

迭代器是 “有状态” 的 —— 一旦next()调用导致done变为true,后续调用不会重置状态,必须重新获取迭代器才能再次遍历。

例如:

const arr = [1, 2];const iterator = arr[Symbol.iterator]();// 第一次遍历iterator.next(); // { value: 1, done: false }iterator.next(); // { value: 2, done: false }iterator.next(); // { done: true }// 尝试再次遍历(无效,因为迭代器已结束)iterator.next(); // { done: true }// 正确做法:重新获取迭代器const newIterator = arr[Symbol.iterator]();newIterator.next(); // { value: 1, done: false }(正常)

六、总结:可迭代对象的核心价值

可迭代对象的本质是 “遵守可迭代协议的对象”,其核心价值在于:

  1. 统一遍历接口:无论数组、字符串、Set 还是自定义集合,都能用for...of、展开运算符等统一语法遍历,降低学习成本和代码复杂度;

  2. 支持丰富的语言特性:为for...of、解构赋值、Array.from()等特性提供底层支撑,拓展了 JS 的集合操作能力;

  3. 灵活性与可扩展性:允许开发者自定义可迭代对象,满足特殊业务场景(如自定义数据结构的遍历)。

掌握可迭代对象,不仅能让你更优雅地处理数据遍历,还能深入理解 JS 的底层设计逻辑 —— 无论是日常开发还是面试,这都是一个不可或缺的知识点。

http://www.dtcms.com/a/535199.html

相关文章:

  • 冠县网站建设公司网页设计图片是怎么显示的
  • 网站下载链接打不开滕州外贸网站建设
  • 塘厦镇仿做网站济宁网站建设(
  • 做爰视频在线观看免费网站网站建设哪方面最重要的呢
  • 做彩平图的素材那个网站有wordpress 装饰公司
  • 如何给wordpress添加网站图标哪里有做配音的兼职网站
  • asp网站栏目如何修改win10建设网站
  • 如何做网站编辑 ?]技术四川建设网共享平台
  • 青岛网站seo公司个人做网站平台
  • 网站建设合同要缴纳印花税吗上海网站建设上海员君
  • 1元涨1000粉丝网站沈阳网站建设024idc
  • 小说网站怎么做流量自己做服务器的网站
  • 网站英文域名是什么二维码生成器联图
  • 网站的整合生产企业解决方案
  • 义乌做网站的公司有哪些大连谷歌seo
  • 有没有专门做家乡图片的网站app推广多少钱一个
  • 山东兴润建设有限公司网站做的好的茶叶网站
  • 平顶山网站制作哪家公司好哈尔滨市建设工程质量安全站
  • 个人做百度云下载网站吗义乌建站
  • 利辛做网站抖音代运营服务协议
  • 网站开发技术及应用做ppt哪些网站的图片质量高
  • 网站建设案例教程视频东莞做网页
  • 关于新农村网络建设网站网站信息查询
  • 织梦怎么制作手机网站源码腾讯云服务器多少钱
  • 什么是网站建设从哪些方面建设网站网络热词缩写
  • 江门网站建设推广策划万户网站制作
  • 做优化网站哪个公司好无锡做公司网站多少钱
  • 柳州住房和城乡建设局网站wordpress sae
  • 铜陵网站建设维护如何做tiktok的数据排行网站
  • 网站做百度百科可视化前端开发工具