Reputation: 3
I want to step recursively through an object for debugging and logging reasons. But my actual code snippet breaks after the first object.
function showData(obj)
{
for(var key in eval(obj))
{
debugWriteLine('object = '+obj+' | property = '+key+' | type = '+typeof(eval(obj+'.'+key))+' | value = '+eval(obj+'.'+key));
if(typeof(eval(obj+'.'+key))=== 'object')
{
obj= obj+'.'+key;
return showData(obj);
}
}
}
showData('$');
This showed me only the content of $ and $.fn but I need all the properties of $.
Thank you Florian
Upvotes: 0
Views: 441
Reputation: 1075567
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>
Upvotes: 1