Traverse and transform objects by visiting every node on a recursive walk
—
Utility methods for extracting information from objects including all possible paths, all node values, and deep cloning with comprehensive type handling and circular reference detection.
Returns an array of all possible non-cyclic paths in the object. Each path is represented as an array of property keys leading from the root to a specific node.
/**
* Get all possible non-cyclic paths in the object
* @returns {Array<Array>} Array of path arrays, each representing a route to a node
*/
traverse(obj).paths()
// Functional version
traverse.paths(obj)Usage Examples:
const traverse = require('traverse');
const obj = {
a: [1, 2],
b: { c: 3 }
};
const allPaths = traverse(obj).paths();
// Result: [
// [], // root path
// ['a'], // array property
// ['a', 0], // first array element
// ['a', 1], // second array element
// ['b'], // object property
// ['b', 'c'] // nested property
// ]
// Complex nested structure
const complex = {
users: [
{ name: 'Alice', tags: ['admin'] },
{ name: 'Bob', tags: ['user', 'guest'] }
]
};
const paths = traverse(complex).paths();
// Includes paths like: ['users', 0, 'name'], ['users', 1, 'tags', 0], etc.Returns an array of all node values in the object in the order they are visited during traversal.
/**
* Get all node values in traversal order
* @returns {Array} Array of all node values encountered during traversal
*/
traverse(obj).nodes()
// Functional version
traverse.nodes(obj)Usage Examples:
const traverse = require('traverse');
const obj = {
a: [1, 2],
b: { c: 3 }
};
const allNodes = traverse(obj).nodes();
// Result: [
// { a: [1, 2], b: { c: 3 } }, // root object
// [1, 2], // array value
// 1, // first number
// 2, // second number
// { c: 3 }, // nested object
// 3 // nested number
// ]
// Extract specific types of nodes
const data = { name: 'test', values: [1, 'two', 3], flag: true };
const nodes = traverse(data).nodes();
const strings = nodes.filter(node => typeof node === 'string');
const numbers = nodes.filter(node => typeof node === 'number');Creates a deep clone of the object with proper handling of circular references, special object types, and prototype chains.
/**
* Create a deep clone of the object with circular reference handling
* @returns {*} Deep cloned copy of the object
*/
traverse(obj).clone()
// Functional version with options
traverse.clone(obj, options)Usage Examples:
const traverse = require('traverse');
// Basic cloning
const original = {
a: 1,
b: [2, 3],
c: { d: 4 }
};
const cloned = traverse(original).clone();
// cloned is a completely separate object
// Circular reference handling
const circular = { name: 'parent' };
circular.self = circular;
circular.children = [{ parent: circular }];
const clonedCircular = traverse(circular).clone();
// Circular references are preserved in the clone
// Special type handling
const complex = {
date: new Date(),
regex: /test/gi,
error: new Error('message'),
typedArray: new Uint8Array([1, 2, 3]),
custom: Object.create({ proto: 'value' })
};
const clonedComplex = traverse(complex).clone();
// All special types are properly clonedThe clone method provides comprehensive support for JavaScript's built-in types:
const arr = [1, [2, 3], { a: 4 }];
const cloned = traverse(arr).clone();
// Creates new array with deeply cloned elementsconst obj = { created: new Date() };
const cloned = traverse(obj).clone();
// Date object is cloned with same timestampconst obj = { pattern: /hello/gi };
const cloned = traverse(obj).clone();
// RegExp is cloned with same pattern and flagsconst obj = { error: new Error('Something went wrong') };
const cloned = traverse(obj).clone();
// Error is cloned with message property preservedconst obj = {
buffer: new Uint8Array([1, 2, 3]),
floats: new Float32Array([1.1, 2.2])
};
const cloned = traverse(obj).clone();
// Typed arrays are properly sliced and clonedfunction CustomClass() { this.value = 42; }
CustomClass.prototype.method = function() { return this.value; };
const obj = { instance: new CustomClass() };
const cloned = traverse(obj).clone();
// Prototype chain is preserved in the cloneconst obj = {
bool: new Boolean(true),
num: new Number(42),
str: new String('hello')
};
const cloned = traverse(obj).clone();
// Object wrappers are properly clonedWhen using the includeSymbols option, symbol properties are included in extraction operations:
const sym1 = Symbol('key1');
const sym2 = Symbol('key2');
const obj = {
normal: 'value',
[sym1]: { [sym2]: 'hidden' }
};
// Default behavior
traverse(obj).paths(); // Excludes symbol paths
traverse(obj).nodes(); // Excludes symbol property values
// With symbol support
traverse(obj, { includeSymbols: true }).paths(); // Includes symbol paths
traverse(obj, { includeSymbols: true }).nodes(); // Includes symbol values
traverse(obj, { includeSymbols: true }).clone(); // Clones symbol propertiesAll extraction methods handle circular references appropriately:
const obj = { name: 'root' };
obj.circular = obj;
obj.nested = { back: obj };
const paths = traverse(obj).paths();
// Stops at circular references, doesn't create infinite paths
const cloned = traverse(obj).clone();
// cloned.circular === cloned (circular structure preserved)
// cloned.nested.back === cloned (maintains relationships)Install with Tessl CLI
npx tessl i tessl/npm-traverse