0

I've created a Javscript prototypal object with a range of attributes. And I need to pass some of these attributes to a function. The function processes the attributes and returns some result.

function ObjCt(id,data) {
    this.id = id;
    this.data = data;
}

So, I'm trying to pass the data of the chart object to a function. Im calling it as:

var obj=new ObjCt(id,data);
process(obj.id,obj.data);

I read from somewhere that passing a value in JS results in a call by value and passing an object results in a call by reference. Here I am trying to call by value, but, seems whatever processing happens in the process() function is reflected in the object obj.

I checked the variable received in the process function using typeof and it comes up as 'object' and not variable. So, what can I do to pass this data as a value?

Edit

I found a rather tiresome workaround. id is primitive and data is a JSON object. So, I tried this in the process() function

JSON.parse(JSON.stringify(data))

Apparently, all references were slashed here. I have a working implementation now, but, Id still love to see if there is an easier way for passing an attribute as a value.

Edit

Solved the problem. As per Paul's answer, tried a normal step by step cloning and another alternative using jquery extend method which goes like this

var object=$.extend(true,{},oldObject);

and passed the newly created object to the process() function.

Please refer this link: What is the most efficient way to deep clone an object in JavaScript?

7
  • Are id and data primitive? Commented Apr 23, 2014 at 12:31
  • 1
    What you want to do is clone the object. You can read more about it here. stackoverflow.com/questions/3774008/cloning-a-javascript-object Commented Apr 23, 2014 at 12:31
  • Sorry for missing that: id is primitive and data is JSON. Commented Apr 23, 2014 at 12:31
  • @Smeegs: Seems an awful lot of work for such a small result. Is there really no other way? Commented Apr 23, 2014 at 12:36
  • Actual JSON (a string) or what everyone thinks JSON is (an object)? Commented Apr 23, 2014 at 12:37

3 Answers 3

2

In JavaScript, primitives (Number, String) are passed ByVal and Objects (including Array, Function) are passed ByRef.

Most of the time this makes no difference, however you can experience problems when using methods which modify an Object without taking into consideration you may want it elsewhere, too.

To get around this, clone your Object before passing it into such a method.

Array has the native Array.prototype.slice to clone, for Objects you need to loop over keys and recurse over the properties.


Custom function to clone, lets you extend it to do more Objects via instanceof testing

function clone(o) {
    var o2 = {}, k;
    if (typeof o !== 'object')
        return o;
    if (o instanceof Array)
        return o.slice().map(clone);
    if (o instanceof Date)
        return new Date(o);
    for (k in o)
        if (Object.prototype.hasOwnProperty.call(o, k))
            o2[k] = clone(o[k]);
    return o2;
}

Cloning via JSON, only things which can be written in JSON are supported

function clone(o) {
    return JSON.parse(JSON.stringify(o));
}

Pretending to clone by using inheritance
This will not protect foo.bar.baz = primitive, but will protect foo.bar = primitive so how good a choice it is for you depends on what the Object looks like or what is being done to it.

function pseudoclone(o) {
    return Object.create(o);
}

Don't try to clone functions, it will go horribly wrong. If you need to modify them somehow, wrap them.

Sign up to request clarification or add additional context in comments.

1 Comment

Thnaks, I implemented cloning the object using jquery's extend method var object = $.extend(true, {}, object)
0

Are you attached to that approach only?

 var Chart=function(id,data){
     this.ObjCt = function () {
          this.id = id;
          this.data = data;
     }
 }

then

  var obj=new Chart(id,data);
   obj.ObjCt();
  //process(obj.id,obj.data);

3 Comments

Chart is not related to this. Was a typo. Changed it in the question. Very sorry.
ok! So Just a question: Why don't you try this? var ObjCt=function(id,data){this.id=id;this.data=data;} and call with var obj=new ObjCt(id,data); //process(obj.id,obj.data);
@Bellash data is still a reference all the way through that.
0

Assuming that id is primitive and data is an object:

function ObjCt(id, data){
    this.id = id;
    this.data = eval(data.toSource());
}

This will clone the object held in data with simple trick.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.