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?

Community
  • 1
  • 1
Mkl Rjv
  • 6,815
  • 5
  • 29
  • 47

3 Answers3

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.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Thnaks, I implemented cloning the object using jquery's extend method var object = $.extend(true, {}, object) – Mkl Rjv Apr 24 '14 at 09:21
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);
Bellash
  • 7,560
  • 6
  • 53
  • 86
  • Chart is not related to this. Was a typo. Changed it in the question. Very sorry. – Mkl Rjv Apr 23 '14 at 12:42
  • 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 Apr 23 '14 at 12:45
  • @Bellash `data` is still a _reference_ all the way through that. – Paul S. Apr 23 '14 at 12:46
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.

ElmoVanKielmo
  • 10,907
  • 2
  • 32
  • 46