js实现一个生成器

//模拟生成器
function read(books) {
    let index = 0
 //返回新对象
    return {
        //这个对象题就是Iterator(遍历器)
        //it有一个方法叫next,每次调用next都会返回一个结果{value,done}
        next(){
            let value = books[index];
            index++;
            let done = index == books.length ? true :false ;

            return { //这里使用了ES6中的同名省略
                value,
                done
            }
        }

    }
}
//it得到返回的新对象,叫做迭代器【将容器中的东西,一次拿出一个,多次拿出,直到拿完】
let it = read(['js','node'])
//it有一个方法叫next,每次调用next都会返回一个结果{value,done}【其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。】

let result;
do{
    result = it.next();
    console.log(result);
}while (!result.done);

结果:
image.png

Iterator(遍历器)

read生成器,用来生成遍历器的,下面代码中遍历器的部分就是第一个return对象中的部分:

//模拟生成器
function read(books) {
    let index = 0
 //返回新对象
    return { 
        //这个对象题就是Iterator(遍历器)
        //it有一个方法叫next,每次调用next都会返回一个结果{value,done}
        next(){
            let value = books[index];
            index++;
            let done = index == books.length ? true :false ;

            return { //这里使用了ES6中的同名省略
                value,
                done
            }
        }

    }
}
//it得到返回的新对象,叫做迭代器【将容器中的东西,一次拿出一个,多次拿出,直到拿完】
let it = read(['js','node'])
//it有一个方法叫next,每次调用next都会返回一个结果{value,done}【其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。】

let result;
do{
    result = it.next();
    console.log(result);
}while (!result.done);

Iterator 的遍历过程是这样的。

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含valuedone两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。【done为true的时候就表示已经遍历完了】

Generator 函数

Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

形式上,Generator 函数是一个普通函数,但是有两个特征。

  1. function关键字与函数名之间有一个星号【*】;

2. 函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。

调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,也就是上一章介绍的遍历器对象(Iterator Object)。

//模拟生成器
function *read(books) {
    for(let item of books){
        yield item;
    }
}
let it = read();
console.log(it);

结果:
image.png

//模拟生成器
function *read(books) {
    for(let item of books){
        yield item;
    }
}
let it = read();
console.log(it);
console.log(it.next());

结果:
image.png

function *read(books) {
    for(let item of books){
        yield item;
    }
}
let it = read(['js','node.js','html','css']);
let result;
do{
    result = it.next();
    console.log(result);
}while (!result.done)

结果:
image.png

小结:

  • Generator 函数内部需要for遍历【它会生成很多个小函数】,遍历体内需要用yield产出一个Iterator 对象;
  • Generator 函数会返回遍历器对象
  • 返回的遍历器有next方法,该方法只要value有值,done就为false【遍历还没有结束】

Set

image.png


//set
var books = new Set();
books.add('js');
books.add('js');
books.add('css');
console.log(books);

image.png

``
let books = new Set();
books.add('js');
books.add('js');
books.add('css');
console.log(books);
console.log(books.size);
console.log(books.has('css'));
books.delete('js');
console.log(books.has('js'));
console.log(books);
books.clear();
console.log(books);
``
image.png

Map

image.png

let books = new Map();
console.log(books);
books.set('js',{name:'js'})
books.set('html',{name:'html'});
books.set('html',{name:'html'});
console.log(books);
console.log(books.size);
console.log(books.get('html'));
books.forEach(function (book) {
    console.log(book);
})
console.log(books.has('js'));
console.log(books.delete('js'));
console.log(books);
books.clear();
console.log(books);

image.png

小结:

  • set中添加是用add()方法,map是用set()方法添加,get()方法获取;
  • 两个方法都会去重
  • set是一个类数组的集合;map是一个类object的集合

素素
37 声望0 粉丝