Javascript is changing variable that needs only to be referenced - javascript

I'm pulling some data from a reference object changing it around for what I need, but for some reason my code is also changing the object i'm referencing..
var obj = {name:"list of things", list:[{name:"thing", 1},{name:"other thing", 2}]};
function doStuff () {
var ref = obj;
for(var p=0;p<ref.list.length;p++){
ref.list.splice(1,1);
}
return ref;
}
For some reason where I'm using this structure in my code, its changing 'obj' as well as 'ref'. can't seem to figure it out

The obj in your example is not an object, it is a reference to an object that lives somewhere in memory. This is why when you do ref=obj, you get another reference to the same object, so changing the object ref references is the same as changing the object obj references.
What you want to do is clone your object, so you end up with two different objects. There are some good answers regarding cloning on StackOverflow and the whole web for that matter. Feel free to use any of those.

JavaScript assignes by reference. You would need to do a deep copy in order to clone an object.
See: http://webdevwonders.com/deep-copy-javascript-objects/

Related

Prevent object created by reference to change when the original one is changed

Probably this thing was talked before but I haven't find a solution to solve my problem yet.
So, my issue is this:
I'm saving into a variable the value of an object.
const aux = this.myObj;
the Object (this.myObj) is changed by some operations after that but I want to save its initial value and be able to re-assing it to it.
Something like:
this.myObj = aux
but as expected, the aux is also modified when the original one is.
Is there a solution to this?
You need to clone the object and save it's data to the other variable.
var clone = Object.assign({}, obj);
In case of nested object, Deep cloning can be achieved using various methods. One of that for a simple structured object with nested key-value pairs.
var clone = JSON.parse(JSON.stringify(obj));
or use library like underscore and lodash.
Object.assign({}, obj) simply copies property values of the given object so it wouldn't a good fix, I would recommend lodash's _.cloneDeep as it does deep cloning for you.
You would just have just to do the following.
const aux = _.cloneDeep(this.myObj)

Why is my array being altered after using slice()?

I'm loading in a variable from my app-config.js file and then copying it with .slice() in an attempt to prevent its state from being mutated. Much to my chagrin, the function I'm using to alter data seems to be failing to respect this attempt at avoiding mutation. mySensitivityVarskeeps changing, although I'm not quite sure how since I'm only directly acting on mySeries. Any ideas as to why this is happening? Here's the code:
var mySeries = mySensitivityVars.slice();
//Dummy Processing Algorithm
function myDummyAlgo(sliderIndex, newValue, range) {
console.log(mySeries[sliderIndex].data)
var modifier = newValue/(range/2)
var newSeries = mySensitivityVars[sliderIndex].data.map(function(num){
return num * modifier
})
console.log(newSeries)
// mySeries[sliderIndex].data = newSeries
// console.log(sensitivityChart.series[0].data)
sensitivityChart.series[sliderIndex].setData(newSeries);
};
Slice can copy the array but any objects that are referenced inside the array are not getting copied (only a reference is copied)
Without seeing the contents of mySensitivityVars it's hard to tell, but my guess is you're mutating a reference to the original object rather than a duplicate object.
Do you have any objects in mySensitivityVars? If so, the corresponding objects in mySeries will be pointing to the original objects in mySensitivityVars rather than standalone duplicates, which is why you're probably seeing the mutation issues.
You should clone the array instead of copying it if you'd like it to be mutated. you can use JSON.parse(JSON.stringify(mySensitivityVars)) which is pretty fast deep cloning technic.
that would ensure new objects are assigned and not copy of the references.
When you do:
mySeries[sliderIndex].data newSeries;
The array mySeries is a copy of mySensitivityVars, but the objects in the array are not copies. Both arrays contain references to the same objects, and modifying the data property affects them both. You need to copy the objects as well:
mySeries = mySentitivyVars.map(o => Object.assign({}, o));
And if the objects contain references to other objects, you may need to do a deep copy. See What is the most efficient way to deep clone an object in JavaScript?

Is there a "native" Javascript function that modifies an object property

Is there a native JavaScript function (or library/module for JavaScript) that modifies a key's value and then returns the full object?
Here's what I've done:
function modifyJSON(jsob, key, val) {
var newjsob = JSON.parse(JSON.stringify(jsob));
newjsob[key] = val;
return newjsob;
}
(Of course, if I wanted to modify the original, I could delete var newjsob... and work with jsob directly.)
This works, but if this type of functionality has already been implemented somewhere, I'd prefer to use that than roll my own.
Your title is a little misleading. What you're doing is deep cloning an existing object and then changing a property on the new object.
If shallow cloning is enough, you could use Object.assign:
var update = {};
update[key] = val;
return Object.assign(jsob, update);
If you need deep cloning, I would check out ImmutableJS. When updating any field on an immutable data structure, a clone of the original structure with your updates applied to it is returned. It's pretty much the exact behavior you're written.
Basically, the difficult part is the deep cloning. Lodash can deep clone the object for you.
https://lodash.com/docs/4.16.2#cloneDeep
function modifyJSON(jsob, key, val) {
var newjsob = _.cloneDeep(jsob);
newjsob[key] = val;
return newjsob
}
After you get the new object, you can just modify the object's property as you desire.
However, be aware that deep copying is slow. Only use it if you must.
https://jsfiddle.net/38kscyxa/

scope variable updated automatically when I am updating another scope variable

I am getting ajax request data and assigning to one scope variable
$scope.customerEvents = data;
then I am using another variable to modify the data
var datanew=data;
datanew.unshift({'customer_events_id': 'ID','date':'Date','event':'Event','eventsubtype':'Event Subtype','eventtype':'Event Type','time':'Time','user_id':'User ID','user_mrn':'User MRN','user_name':'User Name','user_role':'User Role'});
$scope.downloadcsv=datanew;
But customerEvents is getting updated.
you should use:
$scope.customerEvents = angular.copy(data);
Creates a deep copy of source, which should be an object or an array.
That's the documentation.
Also you can look at this question: Javascript equivalent of assign by reference?
Sure, customerEvents and datanew are probably both referencing the same object (referenced by 'data'). Clone the array when you copy it to datanew and you'll be modifying only datanew and eventually $scope.downloadcsv and not customerEvents.
change var datanew=data; to var datanew=data.slice();
you have to do a deep copy of your object unless it will be referenced by the first variable.
you can use:
angular.copy(data)
angular.merge(dst, src) : documentation.
or you can use jquery.clone()
Also you can refer to this post : Deep copying objects in angular?

javascript object remove

Please excuse my question if it doesnt make much sense.
I am using javascript to create a dom element
to do that i create an object ( obj ={}) and fill out the properties as i go, one of which is the dom element to be created. once the element is created and appended to the document i do not need the object to occupy any space in the memory so i was thinking i should remove it.
how would i go about doing that?
thank you
The object's going to exist in memory as soon as it's in the DOM, and the obj property that holds it is really holding a reference to it, not a copy. So as far as I know, the memory required to keep the reference as a property of obj should be negligible. In which case I wouldn't worry about removing it at all.
here is how:
my_var = null;
//or remove it
delete my_var;
if you define you object as locale like
var obj ={}
it will be automatically undefined at the end of the function.

Categories

Resources