I have a situation similar to what you see below. The variable id is set to '03' before the first asynchronous callback is returned. Is there a way to deep copy, or "close" around the variable like you can with blocks in Objective-C? Is there a best practice?
var ids = ['01', '02', '03'];
for(var i=0, i < ids.length; i++){
var id = ids[i];
collection.find({id: ids} function () {
console.log(id);
});
}
The console output is:
03
03
03
There are several ways to do it. One is to iterate with a a method that uses a closure as a callback.
ids.forEach(function (elem) {
collection.find({id: ids} function () {
console.log(elem);
});
});
Creating a closure creates a private scope, which will do what you are expecting.
var ids = ['01', '02', '03'];
for(var i=0, i < ids.length; i++){
var id = ids[i];
(function(index){
collection.find({id: ids}, function () {
console.log(index);
});
})(id);
}
If you use .forEach() instead of a for loop you get the closure for free:
var ids = ['01', '02', '03'];
ids.forEach(function (id) {
collection.find({id: ids} function () {
console.log(id);
});
});
Or if you don't have ES5-isms like .forEach() you can use a self-executing function to close over state. Here we'll just create an innerly-scoped i separate from the parent i:
var ids = ['01', '02', '03'];
for (var i=0; i < ids.length; i++) (function (i) {
var id = ids[i];
collection.find({id: ids} function () {
console.log(id);
});
})(i)
If you are using jQuery. It's easy
var newObject = jQuery.extend(true, {}, oldObject);
That's all you have to do.