I made a FIDDLE for you. I am storing a stack string and then output it, if the property is of primitive type:

function iterate(obj, stack) {
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                    iterate(obj[property], stack + '.' + property);
                } else {
                    console.log(property + "   " + obj[property]);
                    $('#output').append($("<div/>").text(stack + '.' + property))
                }
            }
        }
    }

iterate(object, '')

Update: 17/01/2019

There used to be a different implementation, but it didn't work. See this answer for a prettier solution

Answer from Artyom Neustroev on Stack Overflow
Top answer
1 of 16
122

I made a FIDDLE for you. I am storing a stack string and then output it, if the property is of primitive type:

function iterate(obj, stack) {
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                    iterate(obj[property], stack + '.' + property);
                } else {
                    console.log(property + "   " + obj[property]);
                    $('#output').append($("<div/>").text(stack + '.' + property))
                }
            }
        }
    }

iterate(object, '')

Update: 17/01/2019

There used to be a different implementation, but it didn't work. See this answer for a prettier solution

2 of 16
86

The solution from Artyom Neustroev does not work on complex objects, so here is a working solution based on his idea:

function propertiesToArray(obj) {
  const isObject = val =>
    val && typeof val === 'object' && !Array.isArray(val);

  const addDelimiter = (a, b) =>
    a ? `{b}` : b;

  const paths = (obj = {}, head = '') => {
    return Object.entries(obj)
      .reduce((product, [key, value]) => 
        {
          let fullPath = addDelimiter(head, key)
          return isObject(value) ?
            product.concat(paths(value, fullPath))
          : product.concat(fullPath)
        }, []);
  }

  return paths(obj);
}
  
const foo = {foo: {bar: {baz: undefined}, fub: 'goz', bag: {zar: {zaz: null}, raz: 3}}}
const result = propertiesToArray(foo)
console.log(result)

EDIT (2023/05/23):

4 different (complete) solutions with full descriptions are available on LeetCode: https://leetcode.com/problems/array-of-objects-to-matrix/editorial/?utm_campaign=PostD19&utm_medium=Post&utm_source=Post&gio_link_id=EoZk0Zy9

๐ŸŒ
JavaScript.info
javascript.info โ€บ tutorial โ€บ the javascript language โ€บ advanced working with functions
Recursion and stack
The code is short and easy to understand (hopefully?). Thatโ€™s the power of recursion. It also works for any level of subdepartment nesting. ... We can easily see the principle: for an object {...} subcalls are made, while arrays [...] are the โ€œleavesโ€ of the recursion tree, they give immediate result.
Discussions

javascript - looping through an object (tree) recursively - Stack Overflow
Is there a way (in jQuery or JavaScript) to loop through each object and it's children and grandchildren and so on? If so... can I also read their name? Example: foo :{ bar:'', child:{ g... More on stackoverflow.com
๐ŸŒ stackoverflow.com
javascript recursive through an object - Stack Overflow
I want to step recursively through an object for debugging and logging reasons. More on stackoverflow.com
๐ŸŒ stackoverflow.com
RecursionError: Maximum Recursion Depth Exceeded
To exclude recursion in general sounds wrong to me. More on reddit.com
๐ŸŒ r/ProgrammerHumor
402
26410
March 20, 2022
What is happening when I call JSON and JSON.stringify in the console?
Have you figured out the JSON format? It has a few simple constructs with the same syntax that JS uses: Objects: {} Arrays: [] Numbers: 123 Strings: "123" Booleans: true Null: null Objects have fields which can be any of the above constructs, eg: { "field": "value", "anotherField": 123.456 } Similarly, arrays can contain any of the above constructs as members, eg: [ "Hello", "World", false, null ] The fact that these two constructs can contain any of the other constructs is where the recursion comes in. So an object can contain another object, etc. Eg: [ { "field": "value", "anotherField": 123.456 } "foo", [1, 2, 3] ] Anyway, I'm sure you're aware of how this maps perfectly to how JS objects work. Your job is to take some arbitrary JS object and convert it into JSON like the examples above. The recursion comes from the fact that for every field in an object or element in an array, you must convert that field/element to JSON, too! The base case is when you have an object or array that is empty or one of the leaf types (Number, String, or Boolean). Just note that you'd have to escape the contents of strings to ensure you end up with valid JSON. Normally you'd do this with JSON.stringify, but that's probably a no-go since you're implementing your own version of that function. I believe you should be able to get by with escaping just \ (to \\) and " (to \"). More on reddit.com
๐ŸŒ r/learnprogramming
6
9
September 17, 2015
People also ask

When should I use recursion instead of loops?
Use recursion when dealing with tree-like structures, nested data, or problems that naturally divide into smaller subproblems (like quicksort or mergesort). Use loops for simple iterations. Recursion can be more elegant for complex problems but may use more memory due to the call stack.
๐ŸŒ
playcode.io
playcode.io โ€บ javascript โ€บ recursion
JavaScript Recursion: Complete Guide with Examples | Playcode
What is a stack overflow in recursion?
A stack overflow occurs when too many recursive calls are made, exceeding the call stack limit. This happens when there is no base case, the base case is never reached, or the recursion is too deep. JavaScript engines typically allow 10,000-100,000 stack frames.
๐ŸŒ
playcode.io
playcode.io โ€บ javascript โ€บ recursion
JavaScript Recursion: Complete Guide with Examples | Playcode
What is tail recursion?
Tail recursion is when the recursive call is the last operation in the function. Some languages optimize tail-recursive functions to reuse stack frames, preventing stack overflow. While JavaScript ES6 specifies tail call optimization, most browsers do not implement it.
๐ŸŒ
playcode.io
playcode.io โ€บ javascript โ€บ recursion
JavaScript Recursion: Complete Guide with Examples | Playcode
๐ŸŒ
OpenReplay
blog.openreplay.com โ€บ explaining-recursion-in-javascript
Explaining Recursion in JavaScript
In the preceding code createDeepCopy() is a recursive function. It creates a deep copy of an object passed to it through its input argument.
๐ŸŒ
Medium
medium.com โ€บ swlh โ€บ how-to-use-recursion-to-flatten-a-javascript-object-17e43cc00159
How to Use Recursion to Flatten a JavaScript Object | by amkemp | The Startup | Medium
July 11, 2020 - A walkthrough of a recursive algorithm problem. Given an object oldObj, write a function flattenObject that returns a flattened version of it. If a certain key is empty, it should be excluded from the output.
๐ŸŒ
Programiz
programiz.com โ€บ javascript โ€บ recursion
JavaScript Recursion (with Examples)
Before we wrap up, letโ€™s put your knowledge of JavaScript Recursion to the test! Can you solve the following challenge? Challenge: Write a function to find the nth Fibonacci number. The Fibonacci sequence is a series of numbers where a number is found by adding up the two numbers before it. Starting with 0 and 1, the sequence goes: 0, 1, 1, 2, 3, 5, 8, 13, and so on. Return the nth Fibonacci number for the given n. Check Code ยท Previous Tutorial: JS Hoisting ยท Next Tutorial: JS Object ยท
๐ŸŒ
DEV Community
dev.to โ€บ eellin6 โ€บ manipulating-keys-in-an-object-using-recursion-2cb7
Manipulating Keys in an Object Using Recursion - DEV Community
November 18, 2020 - The final else, if the first two conditions aren't met, will set the new object's key/value equal to the original object's key/value. This will allow the rest of the object's keys that do not match the "newKey" to stay the same after the recursive calls.
Find elsewhere
๐ŸŒ
DEV Community
dev.to โ€บ a_b_102931 โ€บ searching-through-a-nested-object-using-recursion-regular-expressions-and-sets-bm7
Searching Through a Nested Object Using Recursion, Regular Expressions, and Sets - DEV Community
March 11, 2020 - If it is, we will call the function over again--recursion. const searchTerm = "gold" let result = [] function getEachItem(object) { object.forEach(item => { searchItem(item) }) //... }; function searchItem(item) { Object.keys(item).forEach(key => { if (typeof item[key] === "object") { searchItem(item[key]) } //... }) }
๐ŸŒ
CheatCode
cheatcode.co โ€บ blog โ€บ how-to-recursively-traverse-an-object-with-javascript
How to Recursively Traverse an Object with JavaScript | CheatCode
How to write a function that looks for a specific key/value pair on an object and call that function recursively to traverse objects of an arbitrary depth.
๐ŸŒ
Playcode
playcode.io โ€บ javascript โ€บ recursion
JavaScript Recursion: Complete Guide with Examples | Playcode
// Recursion shines with nested structures const fileSystem = { name: "root", children: [ { name: "file1.txt" }, { name: "folder1", children: [ { name: "file2.txt" }, { name: "file3.txt" } ] }, { name: "folder2", children: [ { name: "file4.txt" }, { name: "subfolder", children: [ { name: "file5.txt" } ] } ] } ] }; // Find all file names recursively function getAllFiles(node) { // Base case: no children (it's a file) if (!node.children) { return [node.name]; } // Recursive case: collect files from all children let files = []; for (const child of node.children) { files = files.concat(getAllFiles
๐ŸŒ
Medium
medium.com โ€บ @ronald-roe โ€บ traversing-javascript-objects-by-recursion-8229f7da7915
Traversing JavaScript Objects by Recursion | by Ron Roe | Medium
March 8, 2023 - Used internally to determine where in the pathArray we are * * @returns {any|null} Requested config setting(s) */ const recurseObjectPath = (pathArray, inputObj, level = 0) => { // For each level of the array, get the next path let output; const currPath = pathArray[level]; // Push this object into the output output = inputObj[currPath]; // Prefix increment here will store the new value for us, then // pass it to the index to check, thus checking the next one if (typeof pathArray[++level] !== 'undefined') { // The path goes deeper, recurse into the next index output = recurseObjectPath(pathArray, inputObj[currPath], level); } return output ??
๐ŸŒ
DEV Community
dev.to โ€บ thehomelessdev โ€บ recursion-in-javascript-50nm
Recursion in Javascript - DEV Community
January 24, 2024 - It starts by printing the name of the current node (which is passed as an argument). Then, it loops through the children's array of the current node, and for each child node, it calls itself (recursion, again), passing the child node as the ...
Top answer
1 of 5
123

You're looking for the for...in loop:

for (var key in foo)
{
    if (key == "child")
        // do something...
} 

Be aware that for...in loops will iterate over any enumerable properties, including those that are added to the prototype of an object. To avoid acting on these properties, you can use the hasOwnProperty method to check to see if the property belongs only to that object:

for (var key in foo)
{
    if (!foo.hasOwnProperty(key))
        continue;       // skip this property
    if (key == "child")
        // do something...
}

Performing the loop recursively can be as simple as writing a recursive function:

// This function handles arrays and objects
function eachRecursive(obj)
{
    for (var k in obj)
    {
        if (typeof obj[k] == "object" && obj[k] !== null)
            eachRecursive(obj[k]);
        else
            // do something... 
    }
}
2 of 5
22

You can have an Object loop recursive function with a property execute function propExec built within it.

function loopThroughObjRecurs (obj, propExec) {
  for (var k in obj) {
    if (typeof obj[k] === 'object' && obj[k] !== null) {
      loopThroughObjRecurs(obj[k], propExec)
    } else if (obj.hasOwnProperty(k)) {
      propExec(k, obj[k])
    }
  }
}

Test here:

// I use the foo object of the OP
var foo = {
  bar:'a',
  child:{
    b: 'b',
    grand:{
      greatgrand: {
        c:'c'
      }
    }
  }
}

function loopThroughObjRecurs (obj, propExec) {
  for (var k in obj) {
    if (typeof obj[k] === 'object' && obj[k] !== null) {
      loopThroughObjRecurs(obj[k], propExec)
    } else if (obj.hasOwnProperty(k)) {
      propExec(k, obj[k])
    }
  }
}

// then apply to each property the task you want, in this case just console
loopThroughObjRecurs(foo, function(k, prop) {
  console.log(k + ': ' + prop)
})

๐ŸŒ
JavaScript Tutorial
javascripttutorial.net โ€บ home โ€บ javascript tutorial โ€บ javascript recursive function
JavaScript Recursive Function
November 15, 2024 - This tutorial shows you how to use the recursion technique to develop a JavaScript recursive function, which is a function that calls itself.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ javascript โ€บ how-to-recursively-map-object-in-javascript
How to Recursively Map Object in JavaScript ? - GeeksforGeeks
July 23, 2025 - Recursively mapping objects in JavaScript involves traversing through nested objects and applying a function to each key-value pair.
๐ŸŒ
GitHub
gist.github.com โ€บ sphvn โ€บ dcdf9d683458f879f593
Recursively traverse object javascript, recurse json js, loop and get key/value pair for JSON ยท GitHub
April 3, 2019 - const traverse = function(o, fn, scope = []) { for (let i in o) { fn.apply(this, [i, o[i], scope]); if (o[i] !== null && typeof o[i] === "object") { traverse(o[i], fn, scope.concat(i)); } } } traverse(myObject, (key, value, scope) => { if (value === 'Some Value') { console.log(`Position: myObject[${scope.concat(key).map(k => isNaN(k) ?
๐ŸŒ
Scrimba
scrimba.com โ€บ articles โ€บ javascript-recursion
Quickly learn recursion in JavaScript with examples
March 21, 2023 - Recursion is particularly helpful for solving problems that can be broken down into smaller parts or have an obvious recursive structure, such as traversing a network or searching a data structure such as an object or array.
๐ŸŒ
Medium
medium.com โ€บ @alaneicker โ€บ how-to-process-json-data-with-recursion-dc530dd3db09
Using Recursion in JavaScript to Traverse Nested Data Structures | by Alan Eicker | Medium
March 28, 2023 - Inside the loopThroughJSONfunction, we need to check if the current value is an object or an array. If it is an object, we will call the loopThroughJSON function recursively.
๐ŸŒ
Davidwells
davidwells.io โ€บ snippets โ€บ traverse-object-unknown-size-javascript
Recursively Traverse an object of unknown size in Javascript
September 18, 2016 - function traverse(x) { if (isArray(x)) { traverseArray(x) } else if ((typeof x === 'object') && (x !== null)) { traverseObject(x) } else { } } function traverseArray(arr) { arr.forEach(function (x) { traverse(x) }) } function traverseObject(obj) { for (var key in obj) { if (obj.hasOwnProperty(key)) { traverse(obj[key]) } } } function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]' } // usage: traverse(largeObject) javascript
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ recursively-list-nested-object-keys-javascript
Recursively list nested object keys JavaScript
August 19, 2020 - const people = { Ram: { fullName: 'Ram Kumar', details: { age: 31, isEmployed: true } }, Sourav: { fullName: 'Sourav Singh', details: { age: 22, isEmployed: false } }, Jay: { fullName: 'Jay Grewal', details: { age: 26, isEmployed: true } } } const recursiveSearch = (obj, searchKey, results = []) => { const r = results; Object.keys(obj).forEach(key => { const value = obj[key]; if(key === searchKey && typeof value !== 'object'){ r.push(value); }else if(typeof value === 'object'){ recursiveSearch(value, searchKey, r); } }); return r; }; console.log(recursiveSearch(people, 'age'));
Top answer
1 of 1
1

First: You neither need nor want eval for any of this. Start with $ (the object) and then use obj[key] when you are looking into one of its properties. Recurse when that property is a non-function object.

The reason you're not seeing all of the properties is that for-in loops only loop through enumerable properties, and many of jQuery's properties are not enumerable. You can use getOwnPropertyNames to get the names of all string-keyed properties of an object, even non-enumerable ones. And you can use getPrototypeOf to get that object's prototype so you can enumerate its properties (which for-in does).

So:

function showData(name, obj)
{
    while (obj && obj != Object.prototype)
    {
        // Get all of the object's property names, even non-enumerable ones
        var keys = Object.getOwnPropertyNames(obj);
        keys.forEach(function(key)
        {
            // We should restrict this check to function objects; left
            // as an exercise for the reader...
            if (key !== "caller" &&
                key !== "callee" &&
                key !== "arguments"
                )
            {
                var value = obj[key];
                var type = typeof value;
                debugWriteLine('object = ' + name + ' | property = ' + key + ' | type = ' + type + ' | value = ' + value); 

                if (type === 'object')
                {
                    return showData(name + "." + key, value);
                }
            }
        });

        // Get the object's prototype
        obj = Object.getPrototypeOf(obj);
    }
}

Live Example:

var debugWriteLine = console.log.bind(console);
function showData(name, obj)
{
    while (obj && obj != Object.prototype)
    {
        // Get all of the object's property names, even non-enumerable ones
        var keys = Object.getOwnPropertyNames(obj);
        keys.forEach(function(key)
        {
            // We should restrict this check to function objects; left
            // as an exercise for the reader...
            if (key !== "caller" &&
                key !== "callee" &&
                key !== "arguments"
                )
            {
                var value = obj[key];
                var type = typeof value;
                debugWriteLine('object = ' + name + ' | property = ' + key + ' | type = ' + type + ' | value = ' + value); 

                if (type === 'object')
                {
                    return showData(name + "." + key, value);
                }
            }
        });

        // Get the object's prototype
        obj = Object.getPrototypeOf(obj);
    }
}

showData('$', $);
.as-console-wrapper {
  max-height: 100% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>