东莞市公司网站建设,可以自己做网站的网址,wordpress renderview,长沙做php的网站建设一、可迭代对象#xff08;Iterable object#xff09;
Javascript 可迭代对象是指实现了Symbol.iterator方法的对象#xff0c;该方法返回一个迭代器对象#xff0c;可以通过迭代器对象来遍历对象中的元素。常见的可迭代对象包括数组、字符串、Map、Set等。可以使用for..…一、可迭代对象Iterable object
Javascript 可迭代对象是指实现了Symbol.iterator方法的对象该方法返回一个迭代器对象可以通过迭代器对象来遍历对象中的元素。常见的可迭代对象包括数组、字符串、Map、Set等。可以使用for...of循环或者使用迭代器的next方法来遍历可迭代对象中的元素。
二、Symbol.iterator
Symbol.iterator是一个内置的Symbol对象它是用来定义一个对象的默认迭代器的。当一个对象被迭代时比如使用for…of循环它的Symbol.iterator方法会被调用返回一个迭代器对象。这个迭代器对象具有next()方法用于在对象中的元素上进行迭代。
通过实现Symbol.iterator方法我们可以使一个对象成为可迭代的从而可以使用for…of循环或者其他迭代器方法来遍历对象中的元素。常见的可迭代对象包括数组、字符串、Map、Set等。
下面是一个简单的示例展示了如何使用Symbol.iterator来实现一个可迭代对象
const days {start: new Date(2023-10-01),end: new Date(2023-10-05),[Symbol.iterator]() {return {current: this.start,last: this.end,next() {if(this.current.getTime() this.last.getTime()) {const value this.currentthis.current new Date(this.current.getTime() 24 * 3600 * 1000)return {done: false,value}} else {return {done: true}}}}}
}for(let day of days) {console.log(day)
}为了让 days对象可迭代也就让 for…of 可以运行我们需要为对象添加一个名为 Symbol.iterator 的方法一个专门用于使对象可迭代的内建 symbol。
当 for…of 循环启动时它会调用这个方法如果没找到就会报错。这个方法必须返回一个 迭代器iterator —— 一个有 next 方法的对象。
当 for…of 循环希望取得下一个数值它就调用这个对象的 next() 方法。 next() 方法返回的结果的格式必须是 {done: Boolean, value: any}当 donetrue 时表示循环结束否则 value 是下一个值。
在这里我们也可以结合yield来实现
const days {start: new Date(2023-10-01),end: new Date(2023-10-05),*[Symbol.iterator]() {let current this.startlet last this.endwhile(current.getTime() last.getTime()) {value currentcurrent new Date(current.getTime() 24 * 3600 * 1000)yield value}}
}for(let day of days) {console.log(day)
}迭代对象的实现方式
① 可迭代对象必须实现 Symbol.iterator 方法。objSymbol.iterator 的结果被称为 迭代器iterator。由它处理进一步的迭代过程。 ②一个迭代器必须有 next() 方法它返回一个 {done: Boolean, value: any} 对象这里 done:true 表明迭代结束否则 value 就是下一个值。 Symbol.iterator 方法会被 for…of 自动调用但我们也可以直接调用它。
注内建的可迭代对象例如字符串和数组都实现了 Symbol.iterator。
三、yeild
在JavaScript中yield是ES6ECMAScript 6中的一种关键字用于生成器函数中。通过yield我们可以在生成器函数中暂停执行并返回一个迭代器对象给调用者再次调用时可以从上一次暂停的地方继续执行。
yield 的应用场景包括但不限于以下几个方面
1.惰性求值
通过生成器函数和 yield 关键字可以实现惰性求值即只在需要时才计算值。这对于处理大量数据或者需要耗时计算的场景非常有用。 在 JavaScript 中生成器函数中的 yield语句可以实现惰性求值。惰性求值是一种延迟计算的策略即只在需要值的时候才进行计算。生成器函数的 yield语句可以用于实现这种惰性求值的特性。 下面是一个示例演示了如何在生成器函数中使用 yield 实现惰性求值
function* lazyEvaluation() {let result1 yield calculateResult1();console.log(result1); // 这里会输出第一个结果let result2 yield calculateResult2();console.log(result2); // 这里会输出第二个结果
}function calculateResult1() {console.log(Calculating result 1);return 100;
}function calculateResult2() {console.log(Calculating result 2);return 200;
}let generator lazyEvaluation();// 调用 next() 时并不会立即计算结果而是在需要值的时候才进行计算
let next1 generator.next(); // 这里会输出 Calculating result 1
let next2 generator.next(); // 这里会输出第一个结果然后输出 Calculating result 2
let next3 generator.next(); // 这里会输出第二个结果
在上面的示例中lazyEvaluation 是一个生成器函数其中使用了 yield 语句来实现惰性求值。当调用生成器函数的 next() 方法时计算并返回结果的操作被延迟到真正需要值的时候才进行。这样可以节省计算资源并且使得程序更加高效。
2.异步编程
yield 可以与异步操作结合使用例如使用 Promise 对象。通过 yield 可以简化异步操作的编写使代码更加清晰易懂。 在 JavaScript 中生成器函数中的 yield 语句可以与异步编程结合使用从而实现更加灵活和可读性更高的异步代码。通过结合生成器函数和异步操作可以避免回调地狱callback hell和使用 Promise 的 then 方法时出现的嵌套问题。 下面是一个示例演示了如何在生成器函数中使用 yield 语句实现异步编程
function fakeAsyncAPI(value, delay) {return new Promise(resolve {setTimeout(() {resolve(value);}, delay);});
}function* asyncOperation() {let result1 yield fakeAsyncAPI(First result, 1000);console.log(result1); // 输出: First resultlet result2 yield fakeAsyncAPI(Second result, 500);console.log(result2); // 输出: Second result
}function runAsyncOperation() {let generator asyncOperation();function handleAsyncOperation(result) {let next generator.next(result);if (next.done) {return;}next.value.then(res {handleAsyncOperation(res);});}handleAsyncOperation();
}runAsyncOperation();
3.无限序列
生成器函数可以用于创建无限序列例如斐波那契数列、无限递增的整数等。 在 JavaScript 中可以使用生成器函数和 yield 语句来创建无限序列。生成器函数可以用于按需生成序列中的元素而不需要提前将整个序列存储在内存中。 下面是一个示例演示了如何使用生成器函数和 yield 语句创建一个无限序列
function* infiniteSequence() {let i 0;while (true) {yield i;i;}
}let generator infiniteSequence();console.log(generator.next().value); // 输出: 0
console.log(generator.next().value); // 输出: 1
console.log(generator.next().value); // 输出: 2
// 以此类推可以无限地获取序列中的下一个元素
4.状态机
yield 可以用于实现状态机通过不同的 yield 值来表示不同的状态。 在 JavaScript 中可以使用生成器函数和 yield 语句来实现状态机。状态机是一种用于描述对象在不同状态下的行为的数学模型它包含有限个状态以及在这些状态之间的转换。 下面是一个简单的示例演示了如何使用生成器函数和 yield 语句来实现一个简单的状态机
function* stateMachine() {let state start;while (true) {let input yield state;if (input go) {state running;} else if (input stop) {state stopped;}}
}let machine stateMachine();
console.log(machine.next().value); // 输出: start
console.log(machine.next(go).value); // 输出: running
console.log(machine.next(stop).value); // 输出: stopped
在上面的示例中stateMachine 是一个生成器函数它模拟了一个简单的状态机。每次调用生成器函数的 next() 方法时会返回当前状态并等待传入下一个输入。根据输入的不同状态机会根据规则转换到不同的状态。
通过使用生成器函数和 yield 语句我们可以很容易地实现状态机的逻辑。这种方式使得状态机的代码更加清晰和易于理解同时也可以方便地实现状态之间的转换逻辑。
5.协程函数
实现函数暂停和恢复的协程模式。 在 JavaScript 中yield 关键字通常与生成器函数Generator Function一起使用用于实现协程Coroutine。协程是一种并发编程的模型它允许在不同的执行上下文之间进行切换并且可以保存和恢复执行状态。通过使用yield 和生成器函数可以实现一种简单的协程模型。 在协程函数中yield 可以暂停函数的执行并且可以返回一个值给调用者。调用者可以在需要时恢复协程的执行并且可以传入一个值作为协程函数中 yield 的结果。 下面是一个简单的示例展示了如何使用生成器函数和 yield 实现协程函数
function* coroutineFunction() {let result yield First;console.log(result);result yield Second;console.log(result);
}let coroutine coroutineFunction();console.log(coroutine.next()); // 输出: { value: First, done: false }
console.log(coroutine.next(Hello)); // 输出: Hello// 输出: { value: Second, done: false }
console.log(coroutine.next(World)); // 输出: World// 输出: { value: undefined, done: true }
在这个示例中coroutineFunction 是一个生成器函数通过 yield 实现了协程的暂停和恢复。在调用 coroutine.next() 时协程函数会在每个 yield 处暂停并返回一个对象包含当前的值和是否执行完毕的标志。调用 coroutine.next(value) 时传入的值会作为上一个 yield 的结果并且协程函数会继续执行直到下一个 yield 处。
四、可迭代iterable和类数组array-like
这两个术语看起来差不多但其实大不相同。 Iterable 如上所述是实现了 Symbol.iterator 方法的对象。 Array-like 是有索引和 length 属性的对象所以它们看起来很像数组。 ① 一个可迭代对象也许不是类数组对象。 ② 一个类数组对象可能不可迭代。比如 let arrayLike { // 有索引和 length 属性 类数组对象0: Hello,1: World,length: 2
};// Error (no Symbol.iterator)
for (let item of arrayLike) {}③ 一个对象可能既是类数组对象又是可迭代对象。比如字符串既是可迭代的for…of 对它们有效又是类数组的它们有数值索引和 length 属性。