2017-02-17 28 views
1

Я не знаю, что я делаю неправильно, но этот код после первого исполнения изменяет мой recipesData объект, а на втором исполнении я получаю очень большие переменные (потому что использование кода recipesData).Node.js какого-то образом изменяет свой объект с рекурсивной функцией

Если я использую отладчик объект (recipesData) начинает меняться здесь:

child[child_part] *= craft[part]; 

child еще другая переменная не связана с recipesData.

Это код, я использую:

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; 
} 

ответ

0

Объекты в JavaScript передаются по ссылке, а не значение. Внутри getBasics, craft приведена ссылка на те же базовые данные, что и recipeData. child - это ссылка на один из внутренних объектов recipeData.

Поэтому, когда вы используете *= для присвоения нового значения свойствам в child, он работает с теми же данными, что и переменная recipeData.

+0

Спасибо за ответ, я понимаю основную идею, но до сих пор не знаю, как исправить это без обходного пути, как сделать реальную копию ... –

0

Ребенок ниже - это просто ссылка на recipesData.

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

и, следовательно, позднее модифицирует фактические рецептыДетали. Если вы хотите иметь реальную копию массива, вы можете это сделать, например. с slice() или с concat() как:

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