0
# Object Traversal
1
2
Core traversal methods for iterating through object structures with callback functions. These methods visit every node in the object tree and provide rich context information for transformation and analysis.
3
4
## Capabilities
5
6
### forEach Method
7
8
Executes a callback function for each node in the object, modifying the original object in-place when `this.update()` is called.
9
10
```javascript { .api }
11
/**
12
* Execute callback for each node, modifying object in-place
13
* @param {Function} callback - Function called for each node
14
* @returns {*} The original object (potentially modified)
15
*/
16
traverse(obj).forEach(callback)
17
18
// Functional version
19
traverse.forEach(obj, callback, options)
20
```
21
22
**Usage Examples:**
23
24
```javascript
25
const traverse = require('traverse');
26
27
// Transform negative numbers in-place
28
const obj = { a: 1, b: -2, c: [3, -4] };
29
traverse(obj).forEach(function (x) {
30
if (typeof x === 'number' && x < 0) {
31
this.update(Math.abs(x));
32
}
33
});
34
// obj is now: { a: 1, b: 2, c: [3, 4] }
35
36
// Remove specific values
37
const data = { items: [1, null, 2, undefined, 3] };
38
traverse(data).forEach(function (x) {
39
if (x === null || x === undefined) {
40
this.remove();
41
}
42
});
43
```
44
45
### map Method
46
47
Creates a new object by executing a callback function for each node. The original object remains unchanged.
48
49
```javascript { .api }
50
/**
51
* Create new object by applying callback to each node
52
* @param {Function} callback - Function called for each node
53
* @returns {*} New transformed object
54
*/
55
traverse(obj).map(callback)
56
57
// Functional version
58
traverse.map(obj, callback, options)
59
```
60
61
**Usage Examples:**
62
63
```javascript
64
const traverse = require('traverse');
65
66
// Transform array values
67
const original = { numbers: [1, 2, 3], text: 'hello' };
68
const doubled = traverse(original).map(function (x) {
69
if (typeof x === 'number') {
70
return x * 2;
71
}
72
});
73
// Result: { numbers: [2, 4, 6], text: 'hello' }
74
// original is unchanged
75
76
// Convert strings to uppercase
77
const result = traverse({ a: 'hello', b: { c: 'world' } }).map(function (x) {
78
if (typeof x === 'string') {
79
return x.toUpperCase();
80
}
81
});
82
```
83
84
### reduce Method
85
86
Performs a left-fold reduction on the object, accumulating a single value by visiting each node.
87
88
```javascript { .api }
89
/**
90
* Reduce object to single value using left-fold
91
* @param {Function} callback - Reducer function (acc, node) => newAcc
92
* @param {*} [initialValue] - Optional initial accumulator value
93
* @returns {*} Final accumulated value
94
*/
95
traverse(obj).reduce(callback, initialValue)
96
97
// Functional version
98
traverse.reduce(obj, callback, initialValue)
99
```
100
101
**Usage Examples:**
102
103
```javascript
104
const traverse = require('traverse');
105
106
// Sum all numbers in nested structure
107
const data = { a: 1, b: [2, 3], c: { d: 4, e: [5] } };
108
const sum = traverse(data).reduce(function (acc, x) {
109
return typeof x === 'number' ? acc + x : acc;
110
}, 0);
111
// Result: 15
112
113
// Collect all string values
114
const obj = { name: 'Alice', details: { city: 'NYC', country: 'USA' } };
115
const strings = traverse(obj).reduce(function (acc, x) {
116
if (typeof x === 'string') acc.push(x);
117
return acc;
118
}, []);
119
// Result: ['Alice', 'NYC', 'USA']
120
121
// Count nodes by type
122
const counts = traverse(data).reduce(function (acc, x) {
123
const type = typeof x;
124
acc[type] = (acc[type] || 0) + 1;
125
return acc;
126
}, {});
127
```
128
129
### Traverse Constructor
130
131
Creates a Traverse instance that can be used to call methods. Both `traverse(obj)` and `new traverse(obj)` work identically.
132
133
```javascript { .api }
134
/**
135
* Create traverse instance for an object
136
* @param {*} obj - Object to traverse
137
* @param {TraverseOptions} [options] - Optional traversal options
138
* @returns {Traverse} Traverse instance
139
*/
140
function traverse(obj, options)
141
142
// Constructor form (identical behavior)
143
new traverse(obj, options)
144
145
interface TraverseOptions {
146
immutable?: boolean; // Create immutable copies during traversal
147
includeSymbols?: boolean; // Include symbol properties in traversal
148
}
149
```
150
151
**Usage Examples:**
152
153
```javascript
154
const traverse = require('traverse');
155
156
// Constructor approach
157
const t = traverse({ a: 1, b: 2 });
158
const result = t.map(x => typeof x === 'number' ? x * 2 : x);
159
160
// Direct approach (equivalent)
161
const result2 = traverse({ a: 1, b: 2 }).map(x => typeof x === 'number' ? x * 2 : x);
162
163
// With options
164
const t2 = traverse(obj, { includeSymbols: true, immutable: true });
165
```
166
167
## Options
168
169
### immutable Option
170
171
When set to `true`, creates immutable copies during traversal operations.
172
173
```javascript
174
// Without immutable - may modify object during traversal
175
traverse(obj).forEach(function (x) { /* ... */ });
176
177
// With immutable - preserves original during internal operations
178
traverse(obj, { immutable: true }).forEach(function (x) { /* ... */ });
179
```
180
181
### includeSymbols Option
182
183
When set to `true`, includes symbol properties in the traversal.
184
185
```javascript
186
const sym = Symbol('test');
187
const obj = { a: 1, [sym]: 2 };
188
189
// Default - symbols ignored
190
traverse(obj).nodes(); // Gets: [obj, 1]
191
192
// Include symbols
193
traverse(obj, { includeSymbols: true }).nodes(); // Gets: [obj, 1, 2]
194
```