迭代器模式 (Iterator)

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

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

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

class MyArray {
  private elements: T[];

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

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

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

class ArrayIterator implements Iterator {
  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();
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 方法返回新数组,完成整个操作。

你可能感兴趣的:(设计模式)