Objects in JavaScript are passed by reference. Any changes outside an asynchronous function to such an object are reflected later on in the object itself.
A simple solution is to copy the object by creating a new one which has all properties (and maybe methods...) of the original.
Example for arrays would be this neat little code: [].concat(collection);. But since we're talking objects here, that won't work. With jQuery, this would be as easy as $.extend({}, collection);, but since you didn't tag it, let's make our own version of that method.
function extend( to, from, deep ) {
// Double negation to force deep to be a boolean even if not provided. Thus: defaults to false.
deep = !!deep;
for( var i in from ) {
if( deep ) {
if( typeof from[i] == 'object' ) {
// Array?
if( from[i].length && typeof from[i].splice == 'function' ) {
to[i] = [].concat(from[i]);
}
// nested object!
else {
to[i] = {};
extend(to[i], from[i], deep);
}
}
else {
to[i] = from[i];
}
}
}
return to;
}
Applying it to socket.emit:
socket.emit('object', {
'object' : extend({}, collection, true)
});
Note that circular references will result in an infinite loop when deep copying.