javascript高级部分08----es6之遍历器

1.Iterator遍历器;

   1.1 for...of为什么遍历object对象;
      let obj = {
            name: '张三'
        };
        for (let v of obj) {
            console.log(v);  //obj is not iterable  
        }
  报错原因是obj不是一个迭代器。
  要想能够被for...of正常遍历的,都需要实现一个遍历器Iterator,而数组,Set和Map结构,早就内置好了遍历器Iterator,
  他们的原型中都有一个Symbol.iterator方法,而Object对象没有这个接口,所以不能遍历。
        console.log(Array.prototype[Symbol.iterator]);     //ƒ values() { [native code] }
        console.log(String.prototype[Symbol.iterator]);    //ƒ [Symbol.iterator]() { [native code] }
        console.log(Set.prototype[Symbol.iterator]);       //ƒ values() { [native code] }
        console.log(Map.prototype[Symbol.iterator]);       //ƒ entries() { [native code] }
        console.log(Object.prototype[Symbol.iterator]);    //undefined
     Object原型里面没有iterator迭代器的。
     
     1.2Iterator迭代器原理
        let arr = [1, 2, 3, 4];
        let iter = arr[Symbol.iterator]();
        console.log(iter);
        console.log(iter.next());  //{value: 1, done: false}
        console.log(iter.next());  //{value: 2, done: false}
        console.log(iter.next());  //{value: 3, done: false}
        console.log(iter.next());  //{value: 4, done: false}
        console.log(iter.next());  //{value: undefined, done: true}
   当可遍历对象被for...of遍历的时候,[Symbol.iterator]()就会被调用,返回一个iterator对象,其中里面有一个next()方法,
   会返回一个对象,返回的对象里面有两个参数:value,done,每调用一次next方法,value就会遍历一次可遍历对象里面的属性值,done表示遍历的状态,没有遍历完成的时候,done为false,遍历完成之后done为true,value为undefined;
   

 
    1.3自定义遍历器
      let obj = {
            0: '我是0',
            1: '我是1',
            2: '我是2',
            3: '我是3',
            length: 4,
            [Symbol.iterator]: function() {
                let index = 0;
                return {
                    next: () => {
                        let value = index;
                        let done = index >= this.length;  //当done为true的时候,遍历结束
                        index++
                        return {
                            value,
                            done
                        }
                    }
                }
            }
        }
        for (let v of obj) {
            console.log(v);
            //0 1 2 3 
        }
    此案例较为简单,因为obj里面的属性名为0 1 2 3 对应index,如果属性名不这么简单,那么就需要用Object.keys()方法了。
         let obj = {
            'name': '我是0',
            'age': '我是1',
            'sex': '我是2',
            [Symbol.iterator]: function() {
                let index = 0;
                return {
                    next: () => {
                        let value = Object.keys(obj)[index];
                        let done = index >= Object.keys(obj).length; //当done为true的时候,遍历结束
                        index++
                        return {
                            value,
                            done
                        }
                    }
                }
            }
        }
        for (let v of obj) {
            console.log(v);
            //name age sex
        }

2.Generator函数

      2.1 声明Generator函数
function* Hello(name){
            yield `我的名字是${name}`;
            yield `how are you`;
            yield `怎么样`;
        }
声明的Generator函数与声明普通函数时候的区别:Generator函数在function后面加*号,返回不用return,而是用yield,可以返回多次;

    2.2 Generator函数的调用
function* Hello(name) {
            yield `我的名字是${name}`;
            yield `how are you`;
            yield `怎么样`;
        }
        let gen = Hello('张三');
        console.log(gen.next()); //{value: "我的名字是张三", done: false}
        console.log(gen.next()); //{value: "how are you", done: false}
        console.log(gen.next()); //{value: "怎么样", done: false}
        console.log(gen.next()); //{value: undefined, done: true}

返回的结果是一个对象,里面有next()方法;使用方法和迭代器一样;

 2.3 next方法接收参数
 next()方法可以接受一个参数,它的参数会作为上一个yield的返回值;
function* Hello() {
            let res = yield `hello`;
            yield res;
        }
        let iter = Hello();
        console.log(iter.next());        //{value: "hello", done: false}   
        console.log(iter.next('张三'));  //{value: "张三", done: false}
        console.log(iter.next('lisi'));  //{value: undefined, done: true}

  第一次调用next方法,没有传递参数,res是yield返回的hello,又返回res,所以第一次返回的是hello,第二次传参,‘张三',
  作为上一个yield的返回值,’张三‘替代了’hello‘,此时res就变成了’张三‘,第三次的参数作为第二次的返回值,把第二次的res替代,但是没有第三次的yield,打印第三次的时候,done的状态为true。

  2.4   yield关键字,在Generator函数里面,如果我们想要调用另一个Generator函数,就需要用到关键字yield*;
       function* fn1() {
            yield 'fn1开始';
            yield 'fn1结束';
        }

        function* fn2() {
            yield 'fn2开始';
            yield 'fn2结束'
        }

        function* start() {
            yield 'start';
            yield* fn1();
            yield* fn2();
            yield 'end';
        }
        let ite = start();
        console.log(ite.next());  //{value: "start", done: false} 
        console.log(ite.next());  //{value: "fn1开始", done: false}
        console.log(ite.next());  //{value: "fn1结束", done: false}
        console.log(ite.next());  //{value: "fn2开始", done: false}
        console.log(ite.next());  //{value: "fn2结束", done: false}
        console.log(ite.next());  //{value: "end", done: false}
        console.log(ite.next());  //{value: undefined, done: true}
  1. Set和WeakSet用法
    什么是Set是一种新的数据结构,可以理解为值的集合,它的值不会有重复项;(可以用于数组去重)

    3.1  Set的基本用法:
    
        let s = new Set();
        console.log(s);  //是一个构造函数 Set{}
         
        let s = new Set([1, 2, 3, 4, 5]);
        console.log(s); // {1, 2, 3, 4, 5}         
        3.2 成员值得唯一性
       let s = new Set();
        s.add(1);
        s.add(1);
        console.log(s);  //{1}
     3.3 size属性:获取成员个数
        let s = new Set([1, 2, 3, 4, 5]);
        console.log(s); // {1, 2, 3, 4, 5}
        console.log(s.size);  //5
    3.4  delete属性
       delete()方法:用户删除Set结构中的指定值,删除成功返回:true,删除失败返回:false。
        let s = new Set([1, 2, 3, 4, 5]);
        console.log(s); // {1, 2, 3, 4, 5}
        console.log(s.delete(2)); //true
        console.log(s.delete(8)); //false
        console.log(s); // {1, 3, 5}
3.5  clear方法
  clear()方法:清除所有成员;
       let s = new Set([1, 2, 3, 4, 5]);
        s.clear();
        console.log(s);  //{}
3.6  has()方法:判断set结构中是否含有指定的值。如果有,返回true,如果没有,返回false;
       let s = new Set([1, 2, 3, 4, 5]);
        console.log(s.has(1));  //true
        console.log(s.has(7));  //false
3.7 enteries方法
    返回一个键值对的遍历器
        let s = new Set([1, 2, 3, 4, 5]);
        console.log(s.entries());  //SetIterator {1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5}
  需要注意的是,返回的键名和键值都是同一个值;


  3.8 keys和values方法
  keys()方法:返回键名的遍历器;
  values()方法:返回键值的遍历器;
        let s = new Set([1, 2, 3, 4, 5]);
        console.log(s.keys()); //SetIterator  {1, 2, 3, 4, 5}
        console.log(s.values()); //SetIterator  {1, 2, 3, 4, 5}



        let s = new Set([1, 2, 3, 4, 5]);
        for (let [i, v] of s.entries()) {
            console.log(i);
            console.log(v);
        }
3.7 foreach方法:遍历每一个成员;
        let s = new Set([1, 2, 3, 4, 5]);
        s.forEach(function(value, index) {
            console.log(value, index);
            // 1 1
            // 2 2
            // 3 3
            // 4 4
            // 5 5
        })
      Set用途1:数组去重
       function removal(arr) {
            return Array.from(new Set(arr));
        }
        console.log(removal([1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9])); //[1, 2, 3, 4, 5, 6, 8, 9]

4.Weakset结构:Weakset结构同样不会存储重复的值,不同的是,他的成员必须是对象类型的值

      let ws = new WeakSet([{
            'name': '张三',
            'age': 12
        }]);
        console.log(ws);  //返回一个WeakSet实例化对象
        let ws1 = new WeakSet({
            'name': '李四',
            'age': 24
        });
        console.log(ws1); //报错
 Weakset结构不能遍历,因为它的成员都是对象的弱类型,随时都会被回收机制回收,成员消失,所以Weakset结构不会有keys(),values(),entries(),forEach()等方法和size属性

5.Map的用法;
Map和对象类似,不过对象的属性名是字符串类型的,Map的属性名不再局限于字符串类型,可以是其他类型的;

       let m = new Map();
        console.log(m);   //Map(0) {}
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1);  //Map(2) {"name" => "张三", "age" => 12}
    5.1 set方法
       let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1);
        m1.set(1, 2)
        console.log(m1); //Map(3) {"name" => "张三", "age" => 12, 1 => 2}
   5.2get方法
       let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1.get('name'));  //张三
 5.3 delete方法:删除指定的键值对,删除成功返回:true,删除失败,返回:false;
      let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1.delete('name'));  //ture
  5.4  clear方法():删除Map里面所有的键值对;
  5.5 has():查找是否含有指定的键值对,有就返回true,没有就返回false;
       let m = new Map();
         console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1.delete('name')); //ture
        console.log(m1.has('name')); //false  delete方法已经删除了name
        console.log(m1.has('age'));   //true  
 5.6  entries方法:返回实例的键值对遍历器;
       let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        console.log(m1.entries());  //MapIterator {"name" => "张三", "age" => 12}
5.7 keys()和values()方法;
keys():返回实例所有键名的遍历器;
values():返回实例所有键值的遍历器;
      let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        for (let key of m1.keys()) {
            console.log(key);  //name   age
        }
        for (let value of m1.values()) {
            console.log(value); //张三 12
        }
5.8 forEach()方法:遍历每一个键值对
      let m = new Map();
        console.log(m);
        let m1 = new Map([
            ['name', '张三'],
            ['age', 12]
        ]);
        m1.forEach(function(value, key) {
            console.log(value + ':' + key);
        }) //name:张三  age:12
   5.9 size属性:获取实例的成员数;

6.WeakMap的基本用法:WeakMap结构的键名只支持引用类型的数据;

       let wm = new WeakMap();
        // console.log(wm.set(1, 2));  //报错
        wm.set({
            'name': '张三',
            'age': 12
        }, 2);
        console.log(wm);  //WeakMap {{…} => 2}

WeakMap和Map的区别:WeakMap结构的键名不能是基本数据类型的,而是引用数据类型的,Map结构的键名可以是基本数据类型的。WeakMap都含有get,has,delete方法,但是WeakMap不支持clear方法,不支持遍历,没有keys,values,entries,forEach这四个方法,也没有属性size.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值