共计 2312 个字符,预计需要花费 6 分钟才能阅读完成。
迭代器模式(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 办法返回新数组,实现整个操作。