Savely Krasovsky
Savely Krasovsky

Reputation: 51

Node.js somehow changes my Object with recursive function

I don't know what I am doing wrong but this code after first execution changes my recipesData object, and on second execution I get very big variables (because code use recipesData).

If I use debugger object (recipesData) starts changing here:

 child[child_part] *= craft[part];

child is even another variable not related to recipesData.

This is the code I use:

first ex. second execute.
282       11340
336       69498
390       108918
82        3400
82        3397
27        745
270       10629090
27        19683

// Some object with date
var recipesData = {
    'test1': {
        'example1': 544,
        'example2': 323
    },
    'test2': {
        'example1': 123
    },
}

// Function that I call from main file
module.exports.getFinished = function (item, stock) {
    // Create temp 'recipes' variable
    var recipes = recipesData[item];
    // Execute recursive func
    var basics = getBasics(recipes);

    return basics;
};

// Create 'finished' empty object
var finished = {};

// My recursive fuction that works pretty nice at first
function getBasics(craft) {
    for (var part in craft) {
        for (var recipe in recipesData) {
            if (recipesData.hasOwnProperty(part)) {
                var child = recipesData[part];
                break;
            } else
                child = null;
        }

        if (child) {
            for (var child_part in child)
                // HERE it's CHANGE my 'recipesData' object at the top!
                child[child_part] *= craft[part];
            getBasics(child);
        } else {
            if (finished.hasOwnProperty(part))
                finished[part] += craft[part];
            else
                finished[part] = craft[part];
        }
    }
    return finished;
}

Upvotes: 1

Views: 127

Answers (2)

Janne
Janne

Reputation: 1725

Child below is just reference to the recipesData.

if (recipesData.hasOwnProperty(part)) {
            var child = recipesData[part];
            break;
        } else
            child = null;
    }

and therefore modifies later on actual recipesData. If you want to have real copy of array you can do it e.g. with slice() or with concat() like:

child = [].concat(recipesData[part]);

Upvotes: 0

Nentuaby
Nentuaby

Reputation: 600

Objects in JavaScript are passed by reference, not value. Inside getBasics, craft is a reference to the same underlying data as recipeData. child is a reference to one of recipeData's inner objects.

Therefore, when you use the *= to assign a new value to the properties in child, it's operating on the same data that the recipeData variable references.

Upvotes: 1

Related Questions