在開始分享之前先介紹一個好用 visual studio code 的插件 Quokka.js 安裝后會給我們帶來許多遍歷蚀瘸,我們無需執(zhí)行文件狡蝶,在開發(fā)過程中就可以實時地看到結果。提供兩個版本一個是免費 community 和一個收費 pro 版本贮勃。有錢可以支持一下贪惹,是一個提高開發(fā)效率的好工具随闪。
安裝后只要 shift+command+p 調用命令 Quockka.js:start on current file 就可以在開發(fā)過程實時地觀察到運行結果驶悟。當然提供許多其他的命令大家感興趣可以看一下官方文檔
遍歷
const tuts = [
'angular basic',
'reac basic',
'vue basic',
];
for(const tut of tuts){
}
我們通常會這樣遍歷集合恰梢,來獲取集合每一個元素愧沟。
迭代器
const iterator = tuts[Symbol.iterator]()
iterator{[Iterator]}
for(const tut of tuts){
tut;
}
通過方法集合 tuts[Symbol.iterator]() 的方法玲献,返回返回一個該集合的迭代器供我們使用漫拭,這里有一個相對不好理解 Symbol 州丹,其實 Symbol (符號)是一個 ES6 的新特性表示唯一的屬性给梅,當我們在 javascript 中定義一個接口類寓搬,其中提供一個需要實現(xiàn)該接口的類需要實現(xiàn)的方法就可以通過 Symbol 來定義显蝌,這樣可以避免沖突。
const iterator = tuts[Symbol.iterator]()
每一個集合都有一個迭代器 iterator,獲取 iterator 迭代器之后通過調用iterator.next()方法我們就可以得到一個對象
{ value: 'angular basic', done: false }
這個對象包含兩個屬性分別是 value 和 done曼尊,value 是集合中值而 done 表示集合遍歷是否結束酬诀,當集合沒有更多的值可取,done 屬性為 true 骆撇,value 為 undefined瞒御。
一個實例
首先引入一個可以生產隨機數(shù)的庫 random-number
const randomNumber = require('random-number');
使用 random-number 創(chuàng)建隨機數(shù)很簡單,給出一個取值范圍和數(shù)據(jù)類型就可以得到隨機數(shù)
randomNumber({
min:0,
max:10,
integer:true
})
然后就可以創(chuàng)建是可以生產集合中隨機索引的方法 randomItem神郊,用于為傳入集合中生產一個隨機的索引肴裙。
const randomNumber = require('random-number');
function randomItem(array){
const randomIndex = randomNumber({
min:0,
max:array.length - 1,
integer:true
})
return array[randomIndex]
}
module.exports = randomItem;
創(chuàng)建一個課程生產器用于隨機隨機生產課程。
const randomItem = require('./random-item')
const makeTut = () =>{
const tutSizes = ['big','medium','tiny']
const tutCategory = ['java','javascript','golang']
return randomItem(tutSizes) + ' ' + randomItem(tutCategory)
+ ' ' + 'tut'
}
module.exports = makeTut;
然后就可以測試一下通過調用 makeTut() 然后就生產課程對象
const makeTut = require('./make-tut');
console.log(makeTut());
console.log(makeTut());
console.log(makeTut());
自定義生成器
我們知道一個對象只要實現(xiàn)了Symbol.iterator] 就可以是一個迭代器涌乳,我們就可以 for 循環(huán)來遍歷對象 tutList蜻懦。
const tutList = {
[Symbol.iterator]: ()=>{
return {
next:()=>{
const enoughTut = Math.random() > 0.75
if(!enoughTut){
return {
value:makeTut(),
done:false
}
}
return {done:true}
}
}
}
}
for(const tut of tutList){
console.log(tut);
}
medium golang tut
tiny javascript tut
medium javascript tut
big javascript tut
medium java tut
big java tut
生產器
其實生成器(generator)就是方便生成迭代器(iterator)的語法糖。
生產器函數(shù)與普通函數(shù)不同夕晓,他神奇之處是一個可暫停的函數(shù)宛乃,這個函數(shù)會根據(jù)用戶調用而逐步執(zhí)行。既然他與不同函數(shù)不同為了區(qū)分蒸辆,需要定義時候在 function 后面添加一個星號以便區(qū)別征炼。這個函數(shù)會返回一個迭代器(iterator),函數(shù)內部通過 yield 來返回用于作為 iterator.next() 執(zhí)行時返回的值躬贡。
function* someTuts(){
yield 'angularjs basic tut';
yield 'react basic tut';
yield 'vuejs basic tut';
}
const iterator = someTuts();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
{ value: 'angularjs basic tut', done: false }
{ value: 'react basic tut', done: false }
{ value: 'vuejs basic tut', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
如果 someTuts return 結束后在 return 之后的元素是無法通過迭代取到的谆奥。而且 done 值設置為 true 表示沒有更多的值可取。
function* someTuts(){
yield 'angularjs basic tut';
yield 'react basic tut';
return;
yield 'vuejs basic tut';
}
{ value: 'angularjs basic tut', done: false }
{ value: 'react basic tut', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
如果返回值不是 undefined 而是實際的值拂玻,可以返回該值酸些,但是 done 值也就是 true。generator 是隨著 iterator.next() 的調用而逐步執(zhí)行所以說 generator 是一個可暫停的函數(shù)檐蚜。
function* someTuts(){
yield 'angularjs basic tut';
yield 'react basic tut';
return 'golang basic tut';
yield 'vuejs basic tut';
}
{ value: 'angularjs basic tut', done: false }
{ value: 'react basic tut', done: false }
{ value: 'golang basic tut', done: true }
{ value: undefined, done: true }
function* someTuts(){
while(true){
const enoughTut = Math.random() > 0.75
if(enoughTut) return;
yield makeTut();
}
}
const iterator = someTuts();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
{ value: 'tiny javascript tut', done: false }
{ value: 'tiny javascript tut', done: false }
{ value: 'medium javascript tut', done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
{ value: undefined, done: true }
我們可以通過代碼來簡單地實現(xiàn)一個生成器 generator.
function someTuts(){
let iterations = -1;
const iterator = {
next:()=>{
return { value: 'angular basic tut', done:true}
}
}
return iterator;
}
function someTuts(){
let iterations = -1;
const iterator = {
next:()=>{
iterations++
if(iterations === 0){
return { value: 'angular basic tut', done:false}
}else if(iterations === 1){
return { value: 'react basic tut', done:false}
}else{
return {done:true}
}
}
}
return iterator;
}
通過簡單實現(xiàn)生產器魄懂,大家不難發(fā)現(xiàn)在生成器中是有一個迭代器,迭代器具體控制如何迭代集合熬甚。