4

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>
rene
  • 41,474
  • 78
  • 114
  • 152
ecarrizo
  • 2,758
  • 17
  • 29
  • `Object.keys(object).forEach` is more reliable. – georg Jun 04 '14 at 22:01
  • See [Why is using “for…in” with array iteration such a bad idea?](http://stackoverflow.com/q/500504/1048572) and [How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop](http://stackoverflow.com/q/13296340/1048572) – Bergi Jun 04 '14 at 23:00

2 Answers2

4

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.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
1

You need to use Object.hasOwnProperty function as it's shown here:

var obj = {},
    property;
for (property in obj) {
    if ( obj.hasOwnProperty(property) ) {
        // Your code goes here
    }
}
egasato
  • 406
  • 4
  • 7