JavaScript, overwrite object without losing reference

Anton Gildebrand picture Anton Gildebrand · Aug 26, 2013 · Viewed 15k times · Source

Application

I am working on a simple web application that is built on top of AngularJS. The application should be able to work offline as well as online. When the user is offline, the changes to the data is stored locally. Therefore, the id's that is used within this application in offline mode is only temporary id's, they get replaced when uploaded to the server

Problem

The data that are used in the application consists of complex objects (with relations/references to other objects). When i am saving to the server, i wanted the views to get updated with the new "real" id's. However, since JavaScript works with objects as references im not able to do what i want to: $scope.data = newdata This is not overwriting $scope.data but creates a new object. The old reference to the old data is still there.

Simplified example

var x = {id: 1, name: "myObject"}
var c = x    // c = {id: 1, name: "myObject"}
x = {id: 2, name: "myNewObject"} 
// c = {id: 1, name: "myObject"}

As you can see, c is still a reference to the old object. In practice, this causes that my view isn't updated with new data since it's still bound to the old data. What i need to is to overwrite the properties of, in this example, x. I need to do this recursively since my real objects are complex, however it shouldn't enter any circular references, since this will probably cause stack overflow. If i am overwriting a with b and a has properties that b hasn't got, those properties should be removed.

What i need

I need some sort of function that overwrites all properties in a (old object) with the properties in b (new object). All properties that exists in a but not in b should be removed.

Answer

Boris Marinov picture Boris Marinov · Apr 10, 2014

Using the "extend" method which is available in underscore and jquery:

//Clear all the 'old' properties from the object
for (prop in old_object) {delete old_object[prop]}
//Insert the new ones
$.extend(old_object, new_object)