怀化高速网站,公司管理网站首页,WordPress外链自动转内链,如何销售自己产品方法有哪些2.14.迭代器
2.14.1.for…of
for...of 是 JavaScript ES6 引入的一种新的循环结构#xff0c;#xff0c;用于遍历可迭代对象#xff08;Iterable objects#xff09;的每个元素。
它可以自动调用目标对象的迭代器接口#xff0c;并按顺序逐个访问集合中的每个值。
它…2.14.迭代器
2.14.1.for…of
for...of 是 JavaScript ES6 引入的一种新的循环结构用于遍历可迭代对象Iterable objects的每个元素。
它可以自动调用目标对象的迭代器接口并按顺序逐个访问集合中的每个值。
它可以用来遍历数组、Set、Map、某种类型的字符串、生成器对象Generator object以及其他实现了可迭代协议的对象。
2.14.1.1.用法
// 遍历数组
let numbers [1, 2, 3, 4, 5];
for (let num of numbers) {console.log(num);
}// 输出
// 1
// 2
// 3
// 4
// 5let names [ 王小二, 李小三, 赵小四, 赵小四 ];
for (let name of names) {console.log(name);
}// 输出
// 王小二
// 李小三
// 赵小四
// 赵小四// 遍历字符串
let str hello;
for (let char of str) {console.log(char);
}// 输出
// h
// e
// l
// l
// o// 遍历 Set
let set new Set([ 王小二, 李小三, 赵小四 ]);for (let name of set) {console.log(name);
}// 输出
// 王小二
// 李小三
// 赵小四// 遍历 Map
let map new Map([[name, 王小二], [age, 30]]);
for (let [key, value] of map) {console.log(Key: ${key}, Value: ${value});
}// 输出
// Key: name, Value: John
// Key: age, Value: 30通过 for...of 循环开发者可以更加简洁、直观地遍历多种数据结构
2.14.1.2.和 for...in 比较
for...of 和 for...in 都是 JavaScript 中的循环结构但它们在用途和遍历对象的方式上有所区别
const names [王小二,李不三,赵小四,刘小六];for(let i in names){console.log(i, names[i])
}for(let n of names){console.log(n);
}for…of :
用于遍历可迭代对象Iterable objects如数组、字符串、Set、Map、生成器函数generator function产生的序列等。它会直接遍历并返回数据结构中的实际值或内容。示例
let arr [1, 2, 3];
for (let value of arr) {console.log(value); // 输出1, 2, 3
}for…in:
用于遍历对象Object自身的可枚举属性不包括继承自原型链的属性。它遍历的是对象的键名key而非键值。对于数组使用 for...in 循环可以遍历到非数字索引的属性这通常不是期望的行为除非特别处理。示例
let obj { a: 1, b: 2, c: 3 };
for (let key in obj) {console.log(key); // 输出a, b, cconsole.log(obj[key]); // 输出1, 2, 3
}总结
如果需要遍历数组或其它可迭代对象的实际元素值应使用 for...of。如果要遍历对象的所有自有可枚举属性名则使用 for...in。但在遍历数组时更推荐使用 for...of 或者数组的 forEach() 方法来避免意外包含非数值索引的属性。如果确实需要同时处理数组和其他对象属性可能需要结合使用 for...of 和 Object.keys() 等方法。
2.14.2.迭代器
在 ECMAScript 6ES6中迭代器Iterator是一种接口它为不同的数据结构提供了一种统一的方式来遍历和访问集合中的元素。
迭代器是 JavaScript 中用于顺序访问集合内项目的一种机制。
2.14.2.1.说明 Symbol.iterator为了能够被迭代器遍历一个对象需要在其自身上部署 Symbol.iterator 属性 这个属性的值是一个函数被称为迭代器生成器每次调用该函数都会返回一个新的迭代器对象。 调用函数创建一个指针对象指向当前数据结构的起始位置 第一次调用对象的 next 方法指针自动指向数据结构的第一个成员 接下来不断调用 next 方法指针一直往后移动直到指向最后一个成员 调用next()方法会返回一个包含两个属性的对象value 和 done。 value 属性表示当前迭代位置的值。 done 属性是一个布尔值如果为 true 表示迭代已结束没有更多的元素可以迭代 若为 false则表示还有更多值可以获取并且 value 就是下一个要访问的值。
// Array
const names [王小二,李不三,赵小四,刘小六];let iterator names[Symbol.iterator]();//调用对象的next方法
console.log(iterator.next()); // {value: 王小二, done: false}
console.log(iterator.next()); // {value: 李不三, done: false}
console.log(iterator.next()); // {value: 赵小四, done: false}
console.log(iterator.next()); // {value: 刘小六, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
// Map
let map2 new Map([[name, 王小二],[123, abc],[{ key: objectKey }, Value for object key]
]);
let iterator map2[Symbol.iterator]();
console.log(iterator.next()); // {value: [name, 王小二], done: false}
console.log(iterator.next()); // {value: [123, abc], done: false}
console.log(iterator.next()); // {value: [{…}, Value for object key] , done: false}
console.log(iterator.next()); // {value: undefined, done: true}通过迭代器开发者可以编写更加通用的算法这些算法无需关心底层数据结构的具体实现只要数据结构提供了迭代器接口即可遍历其内容。
同时结合 for...of 循环和其他相关特性如解构赋值迭代器极大地简化了遍历操作的代码编写。
2.14.2.2.支持的类型
原生支持迭代器接口的数据类型包括但不限于
ArrayStringTypedArrayMapSetNodeList 等
2.14.2.3.自定义迭代器
定义对象, 但在调用 for…of 时 , 遍历对象中的数组
通常可以使用 friends.fs.forEach() , 但这样 直接暴露了 fs属性
通过 定义Symbol.iterator属性 返回对象
//声明一个对象
const friends {name: 我的好朋友,fs: [王小二,李小三,赵小四,刘小六],[Symbol.iterator]() {//索引变量let index 0;//let _this this;return {next: function () {if (index _this.fs.length) {const result { value: _this.fs[index], done: false };//下标自增index;//返回结果return result;}else{return {value: undefined, done: true};}}};}
}//遍历这个对象
for (let v of friends) {console.log(v);
}2.15. 生成器
在 ECMAScript 6 (ES6) 中生成器Generators是一种特殊的迭代器生成函数可以暂停执行并保存其上下文状态之后可以恢复执行。
生成器通过 function* 关键字定义
并使用 yield 表达式来产出值或表达式结果。
以下是一个简单的 ES6 生成器示例
function* simpleGenerator() {yield one ;yield two;yield three;
}let generator simpleGenerator();
console.log(generator.next()); // 输出 {value: one , done: false}
console.log(generator.next()); // 输出 {value: two, done: false}
console.log(generator.next()); // 输出 {value: three, done: false}
console.log(generator.next()); // 输出 {value: undefined, done: true} 因为已经没有更多的yield语句了// 或者一次性获取所有产出值
for (let value of simpleGenerator()) {console.log(value);
}/*
输出 :
one
two
three
*/在上述代码中simpleGenerator() 是一个生成器函数每次调用 next() 方法时它都会从上次暂停的地方继续执行到下一个 yield 表达式
并返回一个包含 { value: ..., done: ... } 的迭代器结果对象。当没有更多 yield 表达式时done 属性将为 true表示生成器已完成执行。
生成器在处理异步编程、遍历复杂数据结构以及创建迭代器等方面非常有用。
2.15.1.可以理解为程序的分隔符
function* simpleGenerator() {console.log(第一部分)yield one ;console.log(第二部分)yield two;console.log(第三部分)yield three;console.log(第四部分)
}let generator simpleGenerator();
// 第一部分
console.log(generator.next()); // 输出 {value: one , done: false}
// 第二部分
console.log(generator.next()); // 输出 {value: two, done: false}
// 第三部分
console.log(generator.next()); // 输出 {value: three, done: false}
// 第四部分
console.log(generator.next()); // 输出 {value: undefined, done: true} 因为已经没有更多的yield语句了//
for (let value of simpleGenerator()) {console.log(value);
}
/*
输出 :
第一部分
one
第二部分
two
第三部分
three
第四部分
*/2.15.2.next() 传参
function* simpleGenerator( arg ) {console.log(第一部分 : arg )let aaa yield one ;console.log(第二部分 : aaa )let bbb yield two;console.log(第三部分 : bbb )let ccc yield three;console.log(第四部分 : ccc )
}let generator simpleGenerator(AAA);
// 第一部分 : AAA
console.log(generator.next()); // 输出 {value: one , done: false}
//next方法可以传入实参 // 第二部分 : BBB
console.log(generator.next(BBB)); // 输出 {value: two, done: false}
// 第三部分 : CCC
console.log(generator.next(CCC)); // 输出 {value: three, done: false}
// 第四部分 : DDD
console.log(generator.next(DDD)); // 输出 {value: undefined, done: true} 因为已经没有更多的yield语句了2.15.3.解决回调嵌套
// 异步编程 文件操作 网络操作(ajax, request) 数据库操作
// 这里使用 setTimeout 函数模拟异步操作
// 1s 后控制台输出 111 2s后输出 222 3s后输出 333
// 回调地狱(回调函数嵌套)
// setTimeout(() {
// console.log(111);
// setTimeout(() {
// console.log(222);
// setTimeout(() {
// console.log(333);
// }, 3000);
// }, 2000);
// }, 1000);function one(){setTimeout((){console.log(111);iterator.next();},1000)
}function two(){setTimeout((){console.log(222);iterator.next();},2000)
}function three(){setTimeout((){console.log(333);iterator.next();},3000)
}function * simpleGenerator(){yield one();yield two();yield three();
}//调用生成器函数
let iterator simpleGenerator();
iterator.next();2.15.4.回调传参
//模拟获取 用户数据 订单数据 商品数据
function getUsers(){setTimeout((){let data 用户数据;//调用 next 方法, 并且将数据传入iterator.next(data);}, 1000);
}function getOrders(){setTimeout((){let data 订单数据;iterator.next(data);}, 1000)
}function getGoods(){setTimeout((){let data 商品数据;iterator.next(data);}, 1000)
}function * simpleGenerator(){console.log(开始获取数据);let users yield getUsers();console.log(users);let orders yield getOrders();console.log(orders);let goods yield getGoods();console.log(goods);
}//调用生成器函数
let iterator simpleGenerator();
iterator.next();