Stupid Looping Problem

The default JavaScript object by reference behavior can jump up and cause problems where you don't expect it to, like in this example.

by james young

HTML

<h2>Expected Results</h2>
<em>Formatted for easier reading.</em>
<pre>
{"cards":[
    {"tags":{"CardName":"Goldshire Footman","CardTextInHand":"<b>Taunt</b>"}},
    {"tags":{"CardName":"Placeholder Card","CardTextInHand":"Battlecry:Someone remembers to publish this card."}}
]}
</pre>




<hr>
<h2>Actual Results</h2>
<pre id="results"></pre>




<hr>
<h2>The Problem</h2>
<div>Why do the Actual Results have the second card listed twice, instead of each card listed once?</div>




<hr>
<h2>The Solution</h2>
<div>
Because JavaScript always does shallow copies by reference and not deep clones.
You can find out more details at the following links:
    
<ul>
<li><a href="http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object">http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object</a></li>
<li><a href="http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object">http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object</a></li>
</ul>
    
This being the case, the solution in this example, since there are no functions inside
of temporaryObject, would be to change line 79 from:
    
<blockquote><pre>json.cards.push(temporaryObject);</pre></blockquote>
    
to:
    
<blockquote><pre>json.cards.push(JSON.parse(JSON.stringify(temporaryObject)));</pre></blockquote>
</div>

JavaScript

'use strict';

/*
 * `data` originally came from XML, which is why it is formatted the way it currently is.  
 * The point of this code is to take this JSON created from XML and turn it into a 
 * more JSON like feed for easier processing.
 *
 * Compare the Expected Results to `data` to understand why this is desired.
 *
 * The `data` in this example has been drastically simplified for the purproses of this
 * example as well.
 */

var results = document.getElementById('results'),
    data = {
        "CardDefs": {
            "Entity": [
                {
                    "Tag":[
                        {
                            "_": "Goldshire Footman",
                            "$": {"name": "CardName"}
                        },
                        {
                            "_": "<b>Taunt</b>",
                            "$": {"name": "CardTextInHand"}
                        }
                    ]
                },
                {
                    "Tag": [
                        {
                            "_": "Placeholder Card",
                            "$": {"name": "CardName"}
                        },
                        {
                            "_": "Battlecry:Someone remembers to publish this card.",
                            "$": {"name": "CardTextInHand"}
                        }
                    ]
                }
            ]
        }
    };




function doit(callback) {
    var json = {},
        temporaryObject = {};
    
    json.cards = [];
    
    /* Loop though each Entity (there are two) */
    data.CardDefs.Entity.forEach(function (entity) {
        
        /* Initialize temporaryObject.tags by setting it to be an empty object */
        temporaryObject.tags = {};

        /* Loop though each Tag (there are two on each Entity) */
        entity.Tag.forEach(function (tag) {
            
            /*
             * Add a property onto the temporaryObject.tags object named the value
      ...