I made a small script that iterates and prints the values of one JSON object, if the value of the object is another object or an array, 'll call this work to iterate the value (array or object).
This is me presenting a problem when I print the values of the array and print the values that also adds values within __ proto__ like part of the array
Note you need to have a <ul>
element in your HTML with id jsonUls
to get this code working.
Code:
var json = '{"jsonObject":{"value1":"value2", "array1" : ["value1","value2","value3"]}}'; /* Create Json */
var element = $('#jsonUls');
var object = JSON.parse(json); /* Create object */
/* call the function*/
recursivePrintObjectValues(object, element);
function recursivePrintObjectValues(object, element) {
for(key in object) { /* Iterate the object */
var value = object[key]; /*Get the object value */
/* Verify if value is of type object or an array */
if(typeof value === 'object' || Array.isArray(value)){
/*Generate random */
var random = new Date().valueOf() * Math.random() + 351;
/* Append Li with key */
appendLi(key, '', element);
/*Append UL and get the selector*/
var ul = appendUl(random, element);
/*Call the function with the object and the selector to append (to iterate childs of this object)*/
recursivePrintObjectValues(value, ul);
} else {
appendLi(key, value, element);
}
}
}
function appendUl(random, element) {
var ul = $('<ul></ul>', {
id: random
})
ul.appendTo(element);
return ul;
}
function appendLi(key, value, element) {
if(value == '[object Object]') {
value = '';
}
$('<li></li>', {
text: key + ' : '+ value
}).appendTo(element);
}
The result is the following and I can't figure why and how to avoid it, hopefully anyone can explain me.
<pre>
<ul id="jsonUls">
<li>jsonObject : </li>
<ul id="448773395479.7797">
<li>value1 : value2</li>
<li>array1 : </li>
<ul id="295240780591.31195">
<li>0 : value1</li>
<li>1 : value2</li>
<li>2 : value3</li>
<li>$pnmap$ : function $$JSCompiler_prototypeAlias$$$$pnmap$$($f$$30$$,$opt_obj$$28$$){return $goog$array$map$$.apply($JSCompiler_alias_NULL$$,$pn$aargs_$$(this,arguments))}</li>
<li>$pnforEach$ : function $$JSCompiler_prototypeAlias$$$$pnforEach$$($f$$32$$,$opt_obj$$30$$){$goog$array$forEach$$.apply($JSCompiler_alias_NULL$$,$pn$aargs_$$(this,arguments));return this}</li>
<li>$pnequals$ : function $$JSCompiler_prototypeAlias$$$$pnequals$$($arr2$$13$$,$opt_equalsFn$$2$$){return $goog$array$equals$$.apply($JSCompiler_alias_NULL$$,$pn$aargs_$$(this,arguments))}</li>
<li>$pnfindIndex$ : function $$JSCompiler_prototypeAlias$$$$pnfindIndex$$($f$$41$$,$opt_obj$$43$$){return $goog$array$findIndex$$.apply($JSCompiler_alias_NULL$$,$pn$aargs_$$(this,arguments))}</li>
<li>$pnindexOf$ : function $$JSCompiler_prototypeAlias$$$$pnindexOf$$($obj$$76$$,$opt_fromIndex$$10$$){return $goog$array$indexOf$$.apply($JSCompiler_alias_NULL$$,$pn$aargs_$$(this,arguments))}</li>
</ul>
</ul>
</ul>
</pre>
That's because for...in
iterates over properties inherited from the object's prototype too.
One way to avoid that is check using hasOwnProperty
and reject them:
for(key in object) {
if (!object.hasOwnProperty(key)) continue;
// your other code follows
}
Another option is to use defineProperty
to define non-enumerable properties on the prototype, but this will possibly change the behavior of other parts of your code as well.