This is sometimes useful when debugging/trying to learn a complex JavaScript codebase:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var findOccurences = function(haystack, needle) {
    var visitedObjects = [];
    var occurences = [];
    var queue = [{
        parent: null,
        key: '',
        value: haystack
    }];
    while (queue.length) {
        haystack = queue.shift();
        if (needle(haystack)) {
            occurences.push(haystack);
        } else if (typeof haystack.value === 'object' && !(haystack.value instanceof Error) && visitedObjects.indexOf(haystack.value) < 0) {
            visitedObjects.push(haystack.value);
            for (var i in haystack.value) {
                try {
                  queue.push({
                      parent: haystack,
                      key: i,
                      value: haystack.value[i]
                  });
                } catch(e) {
                  queue.push({
                      parent: haystack,
                      key: i,
                      value: e
                  });
                }
            }
        }
    }
    return {
        referenceList: occurences,
        pathList: occurences.map(function (occurence) {
            var elements = [];
            do {
                elements.push(occurence.key);
                occurence = occurence.parent;
            } while (occurence);
            elements.reverse();
            return elements.join('.');
        })
    };
}