4 / 4 聊一聊Symbol.iterator属性

前面的话

前端每日,巩固基础,不打烊!!!

解答

从一道题来分析:

我们需要向对象person添加什么,以致执行[…person]时,获得形如[‘xiaoq’,20]的输出。

 const person = {
        name: 'xiaoqi',
        age: 20
    }
 //    [...person]; ?  // ['xiaoqi',20] 
 
分析
  • 对象默认不是可迭代的,如果通过[Symbol.iterator]来定义迭代规则,那么对象就是可迭代的。
  • 只有可迭代的对象,才能使用[…person]变成数组,ES6中的数组、Set/Map、字符串都有默认的迭代器和Symbol.iterator属性。
  • 通过生成器Generator返回的迭代器也是可迭代的对象,因为生产器默认会为Symbol.iterator属性赋值
  • 注意:弱引用集合WeakSet与WeakMap集合是不可迭代的。
Symbol.iterator

可迭代对象的Symbol.iterator属性是一个函数:

let list  = [11, 22, 33];
let iterator = list[Symbol.iterator]();
console.log(iterator.next()); // {value: 11, done: false}
创建可迭代对象
let test = {
        items: [11,22, 33],
        *[Symbol.iterator]() {
           for(let item of this.items){
               yield item;
           }
        }
    } 
    for(let item of test) {
        console.log(item);
    }

for ... ofGennerator函数配合使用,这样不需要再调用next方法。

  • Iterator接口主要供for…of消费,for…of循环会自动寻找Iterator接口,默认的Iterator接口部署在数据结构的Symbol.iterator属性,数据结构只要具有Symbol.iterator属性,就一个使用for…of或者…扩展运算符。
  • 类数组:DOM Nodelist, arguments等对象都可以使用for…of与扩展运算符。
回到本题

person不是可迭代对象,使用Symbol.iterator使之成为可遍历的:

const person = {
        name: 'xiaoqi',
        age: 20,
        *[Symbol.iterator]() {
            yield this.name;
            yield this.age;
           
        }
    }

   console.log( [...person]); 

你可能感兴趣的:(#,js)