ES6()

文章详细介绍了JavaScript中的Iterator接口和for...of循环,解释了如何遍历数组、对象、Map和Set等数据结构。此外,还探讨了Generator函数,它是状态机,通过yield表达式控制执行流程,可用于自定义迭代行为,特别是在处理非标准遍历接口的对象时。
摘要由CSDN通过智能技术生成

一、Iterator和for...of循环

1.Iterator遍历器

  • 一是为各种数据结构,提供一个统一的、简便的访问接口
  • 二是使得数据结构的成员能够按某种次序排列
  • Iterator 接口主要供for...of消费

目前知道四种数据集合(Array、Object、Map、Set)

使用方式:

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

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

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

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

返回value(成员值)和done(布尔值:表示遍历是否结束)

var it = makeIterator(['a', 'b']); 

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};//两个属性都是可以省略
    }
  };
}

 没有对应的数据结构,遍历器对象会自己描述了一个数据结构出来

var it = idMaker();//这里没有数据结构

it.next().value // 0
it.next().value // 1
it.next().value // 2
// ...

function idMaker() {
  var index = 0;

  return {
    next: function() {
      return {value: index++, done: false};
    }
  };
}

 2. 默认接口

ES6 规定,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”

const obj = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

原生具备 Iterator 接口的数据结构如下 :

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

3. for...of循环

个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for...of循环遍历它的成员。也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法

替代forEach方法

 使用范围:

Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、 Generator 对象,以及字符串

数组:

  • for...in循环读取键名(下标)
  • for...of循环读取键值
  • 可以借助数组实例的entries方法和keys方法

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}

const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);

for(let v of obj) {
  console.log(v); // red green blue
}

Set和Map 

ar engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
  console.log(e);
}
// Gecko
// Trident
// Webkit

var es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for (var [name, value] of es6) {
  console.log(name + ": " + value);
}
// edition: 6
// committee: TC39
// standard: ECMA-262

类数组对象和字符串

// 字符串
let str = "hello";

for (let s of str) {
  console.log(s); // h e l l o
}

// DOM NodeList对象
let paras = document.querySelectorAll("p");

for (let p of paras) {
  p.classList.add("test");
}

// arguments对象
function printArgs() {
  for (let x of arguments) {
    console.log(x);
  }
}
printArgs('a', 'b');
// 'a'
// 'b'

 对象:不可以直接使用for...of(需要遍历器接口),可以直接使用for...in

let es6 = {
  edition: 6,
  committee: "TC39",
  standard: "ECMA-262"
};

for (let e in es6) {
  console.log(e);
}
// edition
// committee
// standard

for (let e of es6) {
  console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function

//--------------------------------------------
解决方法:将对象转为数组
for (var key of Object.keys(someObject)) {
  console.log(key + ': ' + someObject[key]);
}

二、 Generator 函数

1.Generator函数的说明与使用

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

执行 Generator 函数会返回一个遍历器对象

 Generator 函数是一个普通函数,

  • function关键字与函数名之间有一个星号
  • 函数体内部使用yield表达式
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    var hw = helloWorldGenerator();

 Generator函数就算使用函数调用方式不会直接执行,需要next方法:每次调用时候调用一次方法

yield表达式是暂停执行的标记,而next方法可以恢复执行

hw.next()
// { value: 'hello', done: false }

hw.next()
// { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
// { value: undefined, done: true }

 2.yield表达式

  • 遇到yield表达式,就暂停执行后面的操作
  • 下一次调用next方法时,再继续往下执行
  • 如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止
  • 如果该函数没有return语句,则返回的对象的value属性值为undefined

 3. 场景:为了不具备Interator接口的对象提供遍历操作

      const obj = {
        name: "haha",
        age: 18,
      };
      obj[Symbol.iterator] = objectEntries; //生成器
      function* objectEntries(obj) {
        // 获取对象那个的所有的key
        // 保存到数组中
        const propKeys = Object.keys(obj); //获取对象中的所有key
        for (const propkey of propKeys) {
          // 生成器键值对
          yield [propkey, obj[propkey]];
        }
      }
      console.log(obj);
      //生成器生成之后
      for (let [key, value] of objectEntries(obj)) {
        console.log(`${key},${value} `);
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值