unable to change javascript object property with async, nodejs and mongodb

Problem

I have the following code:

exports.home = function(Comment,User,Activity){
    return function(req, res){  
        var get_url = req.url.split(/\?/)[1];
        if (!req.user)
        {
            res.writeHead(302, {
              'Location': '/'
            });
            res.end();
            return;
        }

        var posts_id_array = req.user.posts_id_array;
        var stocks_array = req.user.watch_list;
        var subscribe_to_arr = req.user.subscribe_to;
        User.find({_id:{$ne:req.user._id, $nin:subscribe_to_arr}}).sort('-_id').limit(10).exec(function(err_user, users){
            Activity.find({$or:[{owner_id : {$in :subscribe_to_arr}},{owner_id:req.user._id}]}).sort('-time_stamp').limit(20).exec(function(err_post,activities){
                 if( err_post || !activities) {
                    res.render('home',{user:req.user,stocks:JSON.stringify(stocks_array)});
                 }
                 else 
                 {
                    var funcArr = [];
                    var hasPost = ["publish","comment","like"];
                    var notPost = ["add_stock","delete_stock"];
                    for(var i =0;i<activities.length;i++)
                    {
                        if(hasPost.indexOf(activities[i].type)!=-1){
                            var fobj = {
                                act: activities[i],
                                f:function(callback){
                                    var test = this.act;
                                    var comments = test.post.comments;
                                    Comment.find({_id:{$in:comments}},function(err,_comments){
                                        console.log("test.post.comments");
                                        //console.log(test.post.comments);
                                        console.log("comments ");
                                        console.log(_comments);
                                        console.log("type");
                                        console.log(typeof test);
                                        console.log("cloning obj");
                                    //  obj = JSON.parse(JSON.stringify(test)); // cloning obj
                                        console.log(test);
                                        console.log("setting value of comments");
                                        **console.log(test.post.comments = _comments);** //unable to  change test.post.comments
                                        console.log("after assignment");
                                        console.log(test.post.comments); // remain unchanged but work with obj.post.comments if I clone test as obj and use obj instead.
                                        callback(null,test);
                                    });
                                }
                            }
                            funcArr.push(fobj.f.bind(fobj));
                        }else{
                            var fobj = {
                                act: activities[i],
                                f :function(callback){
                                    callback(null,this.act);
                                }
                            }
                            funcArr.push(fobj.f.bind(fobj));
                        }
                    }

                    async.series(funcArr,function(err,resArr){
                        console.log("resArr");
                        console.log(resArr);
                        res.render('home',{user:req.user,posts:JSON.stringify(resArr),stocks:JSON.stringify(stocks_array), other_users:JSON.stringify(users)});
                    });
                 }
            });
        }) // end of User.find
    }// end of return function(req,res);
}

I want to update the post.comments property of the "test" object (see ** parts), but I was unable to do so. However, when I cloned the "test" object as "obj" then set "obj.post.comments" it works. Why is it the case? Is it because I messed up some scoping issues?

Thanks.

Problem courtesy of: Jeremy Huang

Solution

I have solved this problem myself. It turns out that I have store mongodb's Schema.Types.ObjectId in the test.post.comments which after some messing around I found cannot be overwritten. When I create a clone of the test object as "obj", the Schema.Types.ObjectId object in obj.post.comments is stored at a different location which allows for modification. My conjecture is that test.post.comments points to a Schema.Types.ObjectId within mongodb itself and therefore cannot be overwritten. When I create a copy of the test object, the problem is therefore resolved.

Solution courtesy of: Jeremy Huang

Discussion

var test = this.act.concat();

use this instead. because arrays substitution in js actually does not copy array but refer original adresses.

for example

var test = ['A','B','C','D'];
var copied = test;
test[0] = 0;
copied[1] = 0;

console.log(test) //0,0,'C','D'
console.log(copied) //0,0,'C','D'

so to avoid this issue, You can use .concat() to copy array if you do not add anything, it will be used as copying.

var test = ['A','B','C','D'];
var copied = test.concat();
test[0] = 0;
copied[1] = 0;

console.log(test) //0,'B','C','D'
console.log(copied) //'A',0,'C','D'
Discussion courtesy of: suish

This recipe can be found in it's original form on Stack Over Flow.