0
function myclass(){

}

myclass.prototype = {
    stuff: {},

    getStuff: function(){
        return Object.keys(this.stuff).length;
    }
};

var m1 = new myclass();
m1.stuff[5] = 'test';
m1.stuff[6] = 'test';

var m2 = new myclass();
m2.stuff[12] = 'test';
m2.stuff[14] = 'test';

alert(m2.getStuff()); // 4 instead of 2 ?!

Can someone plz explain why does the alert print 4?

If I created a new instance of my function, the stuff property should be empty.

thelolcat
  • 10,995
  • 21
  • 60
  • 102
  • You probably want to declare it in the constructor, like `this.stuff = {}` – elclanrs Jan 29 '15 at 23:22
  • Prototype is shared, there is only one instance of stuff and when mutating it changes for all instances. Explained in detail here: http://stackoverflow.com/a/16063711/1641941 – HMR Jan 29 '15 at 23:42

1 Answers1

1

What you are doing here is generally considered bad practice. You don't want to overwrite the prototype, but you want to add to it.

Now to core of your problem. You are defining stuff as an attribute to the prototype. That means any object that is created using that prototype will share that object. If you want each instance to have it's own stuff, it needs to be an instance variable:

function myclass(){
  this.stuff = {};
}

myclass.prototype = {
  getStuff: function(){
    return Object.keys(this.stuff).length;
  }
};

But like I said, don't redefine the prototype, add onto it:

function myclass(){
  this.stuff = {};
}

myclass.prototype.getStuff = function(){
  return Object.keys(this.stuff).length;
}

Now, anything added to stuff will only be added to that particular instance:

var foo = new myclass();
foo.stuff.thing = "Hey, I'm foo";

var bar = new myclass();
bar.stuff.thing = "Hey, I'm bar";

console.log(bar.stuff); //{thing: "Hey, I'm bar"}
Brennan
  • 5,632
  • 2
  • 17
  • 24
  • Once you start to get a handle on how the prototypal inheritance works, it won't feel so counterintuitive – Brennan Jan 30 '15 at 17:00