4

I learn JavaScript's "OOP" models, and looking forward to an advice how can I code around some problem I faced. (I will use the terminology "instance" later however now I know there's no instances in JavaScript.) Consider the following code:

function Class1(){
   this.locvar1 = "locvar1";
   this.locvar2 = "locvar2";
}

function Class2(){
    this.set = function(){     
        this.locvar1 = "ch_locvar1";
    }
} 
Class2.prototype = new Class1;

//we'll get two instances from Class2
var x = new Class2();
x.set();  // we'll change the x's field with that (hoping that)

var y = new Class2();  // hoping that this will be a totally new instance,
                       // and the previous set() won't change it at all

Okay that code will work the way I wanted. I create two new objects, and their prototype will be the same still after I called x.set().

x.locvar1's value: "ch_locvar1"
x.locvar2's value:  "locvar2"

y.locvar1's value:  "locvar1"
y.locvar2's value:  "locvar2"

their prototypes value: 
locvar1 : "locvar1", 
locvar2 : "locvar2"

The problem comes, when I try to use further objects in Class1's field.

function Class1(){
   this.locvar1 = {a : "a"};
   this.locvar2 = "locvar2";
}

function Class2(){
    this.set = function(){     
        this.locvar1.a = "ch_locvar1";
    }
} 
Class2.prototype = new Class1;

var x = new Class2();
x.set();

var y = new Class2();

That will out:

x.locvar1.a's value: "ch_locvar1"
x.locvar2's value:  "locvar2"

what's ok, but..:
y.locvar1.a's value:  "ch_locvar1"
y.locvar2's value:  "locvar2"

their prototypes value: 
locvar1.a : "ch_locvar1", 
locvar2 : "locvar2"

So it seems like with the statement "this.locvar1.a" I change the {a : "a"} object's prototype globally, and not a local instance of "this.locvar1"...

Am I sure on this? How can I code around that? I tried to change "this.locvar1 = new {a : "a"};" because this seems logical to me, but the result is the same.

ssube
  • 47,010
  • 7
  • 103
  • 140

2 Answers2

1

this.locvar1 = new {a : "a"}; is wrong, try this.locvar1 = {a : "ch_locvar1"};.

xdazz
  • 158,678
  • 38
  • 247
  • 274
1

This will give you the prototype inheritance that you were expecting:

function Class1(){
   this.locvar1 = {a : "a"};
   this.locvar2 = "locvar2";
}

function Class2(){
    this.__proto__ = new Class1()
    this.set = function(){     
        this.locvar1.a = "ch_locvar1";
    }
} 

var x = new Class2();
x.set();

var y = new Class2();

document.write(x.locvar1.a) // outputs 'ch_locvar1'
document.write('<br />')    
document.write(y.locvar1.a) // outputs 'a'

I have set the prototype object to a new Class1 when Class2 is instantiated. It doesn't work your way because both Objects will reference the same prototype Object and JavaScript is pass by reference, as others have explained.

Jivings
  • 22,834
  • 6
  • 60
  • 101