ES6迭代器

来源:互联网 发布:硬笔行书字帖 知乎 编辑:程序博客网 时间:2024/06/05 15:34

上一篇博客讲了ES6的for-of循环。实际上,ES6的对象遍历(数组、Map对象、Set对象等)都有一个内置的迭代器方法。


给对象添加迭代器方法

当你给对象添加toString()方法时,就可以将对象显式或隐式的转化为字符串,alert(obj)的时候就会自动弹出toString方法的返回值。同样的,给任意对象添加 myObject[Symbols.iterator]()方法,就可以遍历这个对象了。

Symbols是ES6的新类型。使用Symbols作为命名空间,可以保证不和代码中已有方法冲突。例如,你无法保证该对象是否有 iterator() 方法。


假如你想要让jquery的对象支持for-of循环,可以这样写:

jQuery.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

这段代码的语法看起来会 略显生硬,但是这微乎其微代价却可以为你带来如此多的新特性和新功能,并且你所做 的这一切可以完美地向后兼容。

所有拥有[Symbol.iterator]()的对象被称为可迭代的。你会发现, 可迭代对象的概念几乎贯穿于整门语言之中,不仅是 for-of 循环,还有 Map 和 Set 构造 函数、解构赋值,以及新的展开操作符。

迭代器方法实现

for-of 循环首先调用集合的[Symbol.iterator]()方法,紧接着返回一个新的迭代器对 象。迭代器对象可以是任意具有.next()方法的对象;for-of 循环将重复调用这个方法, 每次循环调用一次。next()方法需要返回一个类似于{value: …, done: [true/false]}的对象

myObject[Symbol.iterator] = function () {  var keys = Object.keys(this).sort();  var index = 0;  return {    next: function () {      return {        value: keys[index], done: index++ >= keys.length      };    }  }}

迭代器对象也可以实现可选的.return()和.throw(exc)方法。如果 for-of 循环过早退出 会调用.return()方法,异常、break 语句或 return 语句均可触发过早退出。如果迭代器需 要执行一些清洁或释放资源的操作,可以在.return()方法中实现。大多数迭代器方法无 须实现这一方法。.throw(exc)方法的使用场景就更特殊了:for-of 循环永远不会调用它。


解构赋值

解构操作同样也接受一个迭代器:

var hello = 'world';var [first, second, …rest] = […hello];console.log(first, second, rest); // w o ["r","l","d"]


0 0