乐趣区

关于设计模式:迭代器模式-Iterator

迭代器模式(Iterator Pattern)是一种行为设计模式,它容许客户端依照特定的形式遍历汇合中的元素,而无需裸露汇合的内部结构。

上面是一个应用 TypeScript 实现的迭代器模式的示例代码:

interface Iterator<T> {next(): T;
  hasNext(): boolean;}

class MyArray<T> {private elements: T[];

  constructor() {this.elements = [];
  }

  add(element: T) {this.elements.push(element);
  }

  getIterator(): Iterator<T> {return new ArrayIterator(this.elements);
  }
}

class ArrayIterator<T> implements Iterator<T> {
  private index: number;
  private readonly elements: T[];

  constructor(elements: T[]) {
    this.index = 0;
    this.elements = elements;
  }

  hasNext(): boolean {return this.index < this.elements.length;}

  next(): T {if (this.hasNext()) {const element = this.elements[this.index];
      this.index++;
      return element;
    }
    return null;
  }
}

// Example usage:
const myArray = new MyArray<number>();
myArray.add(1);
myArray.add(2);
myArray.add(3);

const iterator = myArray.getIterator();
while (iterator.hasNext()) {console.log(iterator.next()); // Output: 1, 2, 3
}

在下面的示例中,MyArray 类示意一个数组,它蕴含一个 getIterator 办法,该办法返回一个迭代器对象。ArrayIterator 类是迭代器的具体实现,它实现了 Iterator 接口中定义的 next 和 hasNext 办法。在 next 办法中,咱们首先查看是否有下一个元素,如果有则返回以后元素,并将索引向前挪动。在 hasNext 办法中,咱们查看以后索引是否小于数组的长度,如果是,则返回 true,否则返回 false。

在应用示例中,咱们创立了一个 MyArray 对象,向其中增加了几个元素,并获取了一个迭代器对象。而后,咱们应用 while 循环遍历迭代器对象并输入每个元素。

总的来说,迭代器模式可能让客户端更不便地遍历汇合对象中的元素,同时还能放弃汇合对象的封装性,进步代码的可维护性

在 JavaScript 中,数组是一个常见的汇合对象,咱们常常须要遍历其中的元素。为了进步代码的可读性和可维护性,JavaScript 提供了许多遍历数组的办法,例如 map、forEach、filter、reduce 等。这些办法都是基于迭代器模式实现的,它们会返回一个迭代器对象,使得咱们能够遍历数组中的每个元素,并对它们进行操作。

以下是 JavaScript 中 Array.prototype.map 办法的简略实现和源码:

function map(arr, callback) {const result = [];
  for (let i = 0; i < arr.length; i++) {result.push(callback(arr[i], i, arr));
  }
  return result;
}

源码实现:

function map(callback, thisArg) {
  // 异样解决,和 forEach 一样
  if (this == null) {throw new TypeError('this is null or not defined');
  }

  // 转为对象
  const O = Object(this);

  // 无符号右移位运算符,保障 len 为 number,且为正整数
  const len = O.length >>> 0;

  // 判断 callback 是否为函数
  if (typeof callback !== 'function') {throw new TypeError(callback + 'is not a function');
  }

  // 返回值数组
  const A = new Array(len);

  // thisArg 为 callback 函数的 this 值
  let k = 0;
  while (k < len) {
    // in 操作符判断属性是否存在
    if (k in O) {const kValue = O[k];
      // 调用 callback 函数,并传入 thisArg、以后值、索引、整个数组
      const mappedValue = callback.call(thisArg, kValue, k, O);
      // 赋值
      A[k] = mappedValue;
    }
    k++;
  }

  return A;
};

Array.prototype.map 办法能够承受一个回调函数作为参数,该函数会被遍历数组中的每个元素调用,并将每个元素转换为一个新的值。在实现中,map 办法会创立一个新的数组,用于存储每个元素的新值,最初返回这个新数组。

在源码中,map 办法首先对传入的 this 值进行了异样解决,而后将其转换为对象。接着,它应用位运算符将数组长度转换为正整数,并判断传入的回调函数是否为函数类型。而后,它创立一个新的数组,应用 while 循环遍历数组中的每个元素,调用回调函数对每个元素进行转换,并将转换后的值存储在新数组中。

最初,map 办法返回新数组,实现整个操作。

退出移动版