目录

  1. 介绍
  2. 实现一个简单的迭代器
  3. 内部迭代器和外部迭代器
  4. 迭代类数组对象
  5. 其他常用迭代器
    1. 倒序迭代器
    2. 中止迭代器

介绍

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部实现。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。


实现一个简单的迭代器

迭代器模式的目的就是实现对聚合对象中的各个元素的循环访问。jQuery 中的 $.each 函数等都是迭代器模式的应用实例。实现一个简单的迭代器并不难,示例代码如下:

  1. var each = function(arr, callback) {
  2. for(var i = 0; i < arr.length; i++) {
  3. callback.call(arr[i], i, arr[i]);
  4. }
  5. }
  6. each([1, 2, 3], function(i, e) {
  7. console.log(i, e);
  8. });

内部迭代器和外部迭代器

迭代器可以分为内部迭代器和外部迭代器,划分依据是迭代规则是在内部还是外部定义的。

前面所写的简单的迭代器属于内部迭代器,在内部定义好迭代规则后,外部只需要一次初始调用即可。

内部迭代器的优点是,外部不用关心迭代器内部的实现,跟迭代器的交互也仅是一次初始调用,但这刚好也是内部迭代器的缺点,由于内部迭代器的迭代规则已经被提前规定,就无法实现两个及两个以上的数组迭代。

外部迭代器必须显式地请求迭代下一个元素,它增加了一些调用的复杂性,同时也增强了迭代器的灵活性,我们可以手动控制迭代的过程或者顺序,一个简单的外部迭代器的实现代码如下:

  1. var Iterator = function(obj) {
  2. var current = 0;
  3. var next = function() {
  4. current += 1;
  5. };
  6. var isDone = function() {
  7. return current >= obj.length;
  8. };
  9. var getCurrItem = function() {
  10. return obj[current];
  11. };
  12. return {
  13. next: next,
  14. isDone: isDone,
  15. getCurrItem: getCurrItem
  16. }
  17. };

迭代类数组对象

迭代器模式除了可以迭代数组,还能迭代字符串、arguments等类数组对象,jQuery 里的 $.each 方法封装的迭代行为如下:

  1. $.each = function(obj, callback) {
  2. var value,
  3. i = 0,
  4. length = obj.length;
  5. if (obj.constructor === Array) {
  6. for(; i < length; i++) {
  7. value = callback.call(obj[i], i, obj[i]);
  8. if (value === false) {
  9. break;
  10. }
  11. }
  12. } else {
  13. for(i in obj) {
  14. value = callback.call(obj[i], i, obj[i]);
  15. if (value === false) {
  16. break;
  17. }
  18. }
  19. }
  20. return obj;
  21. }

其他常用迭代器

倒序迭代器

迭代器模式提供了循环访问一个聚合对象中每个元素的方法,但它没有规定我们以顺序、倒序还是中序来循环遍历一个对象,一个简单的倒序迭代器的实现代码如下:

  1. var reverseEach = function(ary, callback) {
  2. for(var l = ary.length - 1; l >= 0; l--) {
  3. callback(l, ary[l]);
  4. }
  5. };

中止迭代器

所谓中止迭代器,就是封装了一个类似 break 的可以跳出循环的功能,实现代码如下:

  1. var each = function(ary, callback) {
  2. for(var i = 0; i < ary.length; i++) {
  3. if (callback(i, ary[i]) === false) {
  4. break;
  5. }
  6. }
  7. };

  1. ID : 39
  2. DATE : 2017/11/6
  3. AUTHER : WJT20
  4. TAG : JavaScript