0
# Iterator Utilities
1
2
Core synchronous iteration functionality for working with Iterables, Array-like objects, and testing for iteration support. These utilities enable libraries to accept multiple collection types with consistent behavior across all JavaScript environments.
3
4
## Capabilities
5
6
### Symbol Constants
7
8
#### $$iterator
9
10
Symbol used as the property name for iterator methods. Represents `Symbol.iterator` when available, falls back to `"@@iterator"` for legacy environments.
11
12
```javascript { .api }
13
/**
14
* Property name for iterator method, used for creating new Iterables
15
* @type {Symbol|string}
16
*/
17
export const $$iterator: unique symbol;
18
```
19
20
**Usage Example:**
21
22
```javascript
23
import { $$iterator } from "iterall";
24
25
function Counter(to) {
26
this.to = to;
27
}
28
29
Counter.prototype[$$iterator] = function() {
30
return {
31
to: this.to,
32
num: 0,
33
next() {
34
if (this.num >= this.to) {
35
return { value: undefined, done: true };
36
}
37
return { value: this.num++, done: false };
38
}
39
};
40
};
41
42
const counter = new Counter(3);
43
for (const number of counter) {
44
console.log(number); // 0, 1, 2
45
}
46
```
47
48
### Type Checking Functions
49
50
#### isIterable
51
52
Tests if an object implements the Iterator protocol via `Symbol.iterator` or `"@@iterator"` method.
53
54
```javascript { .api }
55
/**
56
* Tests if object implements Iterator protocol
57
* @param obj - Value to test for Iterable protocol
58
* @returns true if object is Iterable
59
*/
60
function isIterable(obj: any): obj is Iterable<any>;
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
import { isIterable } from "iterall";
67
68
isIterable([1, 2, 3]); // true - Arrays are iterable
69
isIterable("ABC"); // true - Strings are iterable
70
isIterable(new Map()); // true - Maps are iterable
71
isIterable(new Set()); // true - Sets are iterable
72
isIterable({ length: 3 }); // false - Array-like but not iterable
73
isIterable({ key: "value" }); // false - Plain objects are not iterable
74
```
75
76
#### isArrayLike
77
78
Tests if an object implements the Array-like protocol via defining a positive-integer `length` property.
79
80
```javascript { .api }
81
/**
82
* Tests if object implements Array-like protocol
83
* @param obj - Value to test for Array-like protocol
84
* @returns true if object is Array-like
85
*/
86
function isArrayLike(obj: any): obj is { length: number };
87
```
88
89
**Usage Examples:**
90
91
```javascript
92
import { isArrayLike } from "iterall";
93
94
isArrayLike([1, 2, 3]); // true - Arrays are array-like
95
isArrayLike("ABC"); // true - Strings have length
96
isArrayLike({ length: 1, 0: "A" }); // true - Has numeric length
97
isArrayLike(new Map()); // false - No length property
98
isArrayLike({ key: "value" }); // false - No length property
99
```
100
101
#### isCollection
102
103
Tests if an object is either Iterable or Array-like. Excludes string literals but includes Arrays and other collection types.
104
105
```javascript { .api }
106
/**
107
* Tests if object should be iterated over (Iterable or Array-like, excluding strings)
108
* @param obj - Object value to test
109
* @returns true if object is a collection that should be iterated
110
*/
111
function isCollection(obj: any): obj is Iterable<any> | { length: number };
112
```
113
114
**Usage Examples:**
115
116
```javascript
117
import { isCollection, forEach } from "iterall";
118
119
isCollection([1, 2, 3]); // true - Arrays
120
isCollection("ABC"); // false - Strings excluded
121
isCollection({ length: 1, 0: "A" }); // true - Array-like objects
122
isCollection(new Map()); // true - Iterable objects
123
isCollection({ key: "value" }); // false - Plain objects
124
125
// Common usage pattern
126
if (isCollection(obj)) {
127
forEach(obj, (value) => {
128
console.log(value);
129
});
130
}
131
```
132
133
### Iterator Creation and Access
134
135
#### getIterator
136
137
Returns the Iterator object if the provided object implements the Iterator protocol, otherwise returns undefined.
138
139
```javascript { .api }
140
/**
141
* Gets Iterator from an Iterable object
142
* @param iterable - Iterable object to get Iterator from
143
* @returns Iterator instance or undefined
144
*/
145
function getIterator<TValue>(iterable: Iterable<TValue>): Iterator<TValue>;
146
function getIterator(iterable: any): void | Iterator<any>;
147
```
148
149
**Usage Example:**
150
151
```javascript
152
import { getIterator } from "iterall";
153
154
const iterator = getIterator([1, 2, 3]);
155
if (iterator) {
156
console.log(iterator.next()); // { value: 1, done: false }
157
console.log(iterator.next()); // { value: 2, done: false }
158
console.log(iterator.next()); // { value: 3, done: false }
159
console.log(iterator.next()); // { value: undefined, done: true }
160
}
161
```
162
163
#### getIteratorMethod
164
165
Returns the method responsible for producing the Iterator object. Used for performance tuning in rare cases.
166
167
```javascript { .api }
168
/**
169
* Gets the @@iterator method from an Iterable object
170
* @param iterable - Iterable object with @@iterator method
171
* @returns @@iterator method or undefined
172
*/
173
function getIteratorMethod<TValue>(iterable: Iterable<TValue>): () => Iterator<TValue>;
174
function getIteratorMethod(iterable: any): void | (() => Iterator<any>);
175
```
176
177
**Usage Example:**
178
179
```javascript
180
import { getIteratorMethod } from "iterall";
181
182
const myArray = [1, 2, 3];
183
const method = getIteratorMethod(myArray);
184
if (method) {
185
const iterator = method.call(myArray);
186
console.log(iterator.next()); // { value: 1, done: false }
187
}
188
```
189
190
#### createIterator
191
192
Creates an Iterator for both Iterable and non-Iterable Array-like collections. Provides universal Iterator creation with fallback support.
193
194
```javascript { .api }
195
/**
196
* Creates Iterator from Iterable or Array-like collection
197
* @param collection - Iterable or Array-like object
198
* @returns Iterator instance or undefined
199
*/
200
function createIterator<TValue>(collection: Iterable<TValue>): Iterator<TValue>;
201
function createIterator(collection: { length: number }): Iterator<any>;
202
function createIterator(collection: any): void | Iterator<any>;
203
```
204
205
**Usage Examples:**
206
207
```javascript
208
import { createIterator } from "iterall";
209
210
// Works with Iterables
211
const iterableIterator = createIterator([1, 2, 3]);
212
213
// Works with Array-like objects
214
const arrayLike = { length: 3, 0: "Alpha", 1: "Bravo", 2: "Charlie" };
215
const arrayLikeIterator = createIterator(arrayLike);
216
217
if (arrayLikeIterator) {
218
console.log(arrayLikeIterator.next()); // { value: "Alpha", done: false }
219
console.log(arrayLikeIterator.next()); // { value: "Bravo", done: false }
220
console.log(arrayLikeIterator.next()); // { value: "Charlie", done: false }
221
console.log(arrayLikeIterator.next()); // { value: undefined, done: true }
222
}
223
```
224
225
### Iteration Utilities
226
227
#### forEach
228
229
Iterates over Iterable or Array-like collections, calling a callback at each iteration. Delegates to native `forEach` when available for optimal performance.
230
231
```javascript { .api }
232
/**
233
* Iterates over collection, calling callback for each item
234
* @param collection - Iterable or Array-like object to iterate
235
* @param callbackFn - Function called for each item (value, index, collection)
236
* @param thisArg - Optional value to use as 'this' in callback
237
*/
238
function forEach<TCollection extends Iterable<any>>(
239
collection: TCollection,
240
callbackFn: (value: ValueOf<TCollection>, index: number, collection: TCollection) => any,
241
thisArg?: any
242
): void;
243
function forEach<TCollection extends { length: number }>(
244
collection: TCollection,
245
callbackFn: (value: any, index: number, collection: TCollection) => any,
246
thisArg?: any
247
): void;
248
```
249
250
**Usage Examples:**
251
252
```javascript
253
import { forEach } from "iterall";
254
255
// Basic iteration
256
forEach([1, 2, 3], (value, index) => {
257
console.log(`Index ${index}: ${value}`);
258
});
259
260
// Works with any collection type
261
forEach(new Set(["a", "b", "c"]), (value) => {
262
console.log(value);
263
});
264
265
// Array-like objects
266
const nodeList = document.querySelectorAll("div");
267
forEach(nodeList, (element, index) => {
268
element.textContent = `Div ${index}`;
269
});
270
271
// Using thisArg
272
const context = { prefix: "Item: " };
273
forEach([1, 2, 3], function(value) {
274
console.log(this.prefix + value);
275
}, context);
276
```
277
278
**Error Handling:**
279
280
The `forEach` function includes protection against infinite iterators:
281
282
```javascript
283
// Will throw TypeError after 9,999,999 iterations
284
// "Near-infinite iteration."
285
```
286
287
**Performance Notes:**
288
289
- Delegates to native `Array.prototype.forEach` when available
290
- Uses optimized for-loops for Array-like objects
291
- Skips "holes" in Array-like objects (following ECMAScript specification)