0

Consider the following code

var myData = {name: 'John'};

function fixName(data) {
    var newData = data;
    newData.name = 'Mike';
    return newData;
}

var myData2 = fixName(myData);
console.log(myData2.name);
console.log(myData.name);

'Mike' is printed twice because within my function, newData and myData point to the same thing. How can I alter my function so that it has no side effects upon myData? This means the program should print 'Mike' then 'John'.

deltanovember
  • 42,611
  • 64
  • 162
  • 244

4 Answers4

4

You might want to take a look at this answer for an explanation about "cloning" an object (which is really complex), or take the easy route and use jQuery extend provided by J.Resig himself which technically abstracts this cloning code into a simple syntax

Community
  • 1
  • 1
Joseph
  • 117,725
  • 30
  • 181
  • 234
2

So basically you want to create a copy of an object instead of getting a reference?

If this is the case, you may be interested in this question where the accepted answer uses a simple piece of jQuery to do it.

If, like me, you don't want to use jQuery, you can just use a loop to get a basic copy:

var myData2 = {};
for( var x in myData) if( myData.hasOwnProperty(x)) myData2[x] = myData[x];
// Copied!

This is actually enough for any object that is just being used as an associative array (as yours appears to be, and as most JSON objects are).

Community
  • 1
  • 1
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
1

You need to clone that data object.

What is the best way to clone an object is answered here

// jQuery
newData = $.extend({}, data);
Community
  • 1
  • 1
drinchev
  • 19,201
  • 4
  • 67
  • 93
1

To clone myData, you could use JSON.parse(JSON.stringify(myData)):

var myData = {name: 'John'};

function fixName(data) {
    var newData = data;
    newData.name = 'Mike';
    return newData;
}

var myData2 = fixName( JSON.parse(JSON.stringify(myData)) );
console.log(myData2.name); //=> Mike
console.log(myData.name);  //=> John

This will clone nested objects too, by the way.

It may be an idea to make a function out of it:

function cloneObj(obj,reviver){
  return JSON.parse(JSON.stringify(obj),reviver);
}

Where reviver could be used to manipulate data in the object, in your case that would make fixName obsolete.

var myData2 = cloneObj(myData, function(k,v){return k === 'name' ? 'Mike' : v;});
KooiInc
  • 119,216
  • 31
  • 141
  • 177