Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I preserve a copy of an object, inside that object when its created - Continued:

This is continuation of My Old Question

This is my function which creates a new student object:

function student(id, name, marks, mob, home){
    this.id = id;
    this.name = name;
    this.marks = marks;
    this.contacts = {};
    this.contacts.mob = mob;
    this.contacts.home = home;

    this.toContactDetailsString = function(){
        return this.name +':'+ this.mob +', '+ this.home
    }
}

I would like to create a copy of the object when it is initialized inside that object: I came up with this:

function student(id, name, marks, mob, home){
    this.id = id;
    this.name = name;
    this.marks = marks;
    this.contacts = {};
    this.contacts.mob = mob;
    this.contacts.home = home;

    this.toContactDetailsString = function(){
        return this.name +':'+ this.mob +', '+ this.home
    }
    this.baseCopy = this; //Not sure about this part
}

But the problem is its giving me a infinite loop of copies of current object in baseCopy; ANd also it is automatically updating when ever I update any attributes of my object.

1. How is this possible such that, I can preserve a copy of an object with the initial values, inside that object when its created?

2. Is it possible not to copy the functions

3. I'm very curious to know if this is possible without hard-coding attribute names and by using pure JS

like image 374
Akhil Sekharan Avatar asked Dec 20 '12 09:12

Akhil Sekharan


2 Answers

Pretty much like my answer on your previous question, you can use this code to make a copy of the object and it's nested properties, while not copy-ing it's functions:

function student(id, name, marks, mob, home){
    this.id = id;
    this.name = name;
    this.marks = marks;
    this.contacts = {};
    this.contacts.mob = mob;
    this.contacts.home = home;

    this.toContactDetailsString = function(){
        return this.name +':'+ this.mob +', '+ this.home
    }

    // Copy the object to baseCopy 
    this.baseCopy = clone(this); // "clone" `this.baseCopy`
}

function clone(obj){
    if(obj == null || typeof(obj) != 'object'){ // If the current parameter is not a object (So has no properties), return it;
        return obj;
    }

    var temp = {};
    for(var key in obj){ // Loop through all properties on a object
        if(obj.hasOwnProperty(key) && !(obj[key]  instanceof Function)){ // Object.prototype fallback. Also, don't copy the property if it's a function.
            temp[key] = clone(obj[key]);
        }
    }
    return temp;
}

var s = new student(1, 'Jack', [5,7], 1234567890, 0987654321);
s.marks = s.marks.concat([6,8]); // Jack's gotten 2 new marks.

console.log(s.name + "'s marks were: ", s.baseCopy.marks);
// Jack's marks were:  [5, 7]
console.log(s.name + "'s marks are: ", s.marks);
// Jack's marks are:  [5, 7, 6, 8]
console.log(s.baseCopy.toContactDetailsString); // check if the function was copied.
// undefined
console.log(s.baseCopy.contacts.mob);
// 1234567890

(I'll work on the deep copy for a sec)

The "deep" copy should work now.

like image 71
Cerbrus Avatar answered Oct 24 '22 22:10

Cerbrus


you are not creating a copy by saying

this.baseCopy = this; , you are just setting the reference to this inner variable. So baseCopy is also pointing to same object

You need to create a method which will return a new student object from passed student object and then store that as BaseCopy

like image 35
Subin Sebastian Avatar answered Oct 25 '22 00:10

Subin Sebastian