tags:

views:

154

answers:

3

i have the below prog

  Object.prototype.inherit = function(baseConstructor) {
  this.prototype = (baseConstructor.prototype);
  this.prototype.constructor = this;
};
Object.prototype.method = function(name, func) {
  this.prototype[name] = func;
};

function StrangeArray(){}
StrangeArray.inherit(Array);
StrangeArray.method("push", function(value) {
  Array.prototype.push.call(this, value);
});

var strange = new StrangeArray();
strange.push(4);
alert(strange);

and when irun it i get stack over flow? any ideas why?

+6  A: 

You're setting StrangeArray.prototype to Array.prototype. Later, you're adding a push method to StrangeArray.prototype (which is now the same thing as Array.prototype). So you're effectively setting Array.prototype.push. Your push method calls Array.prototype.push - i.e. itself. So it ends up just calling itself repeatedly and you get a stack overflow.

Jon Bright
thank u very much
ravi
+2  A: 

Jon is right. Here's a way to fix it. Instead of setting StrangeArray.prototype to Array.prototype, this will let you set StrangeArray.prototype to a new instance of Array, so it inherits Array.prototype's properties (without calling Array's constructor).

Object.prototype.inherit = function(baseConstructor) {
  var tmp = Function();
  tmp.prototype = baseConstructor.prototype;
  this.prototype = new tmp();
  this.prototype.constructor = this;
};


Edit:

this.prototype = new baseConstructor();

works in this example, but is not good in more complex programs. If the base constructor does some initialization, such as creating DOM elements, incrementing a count, or connecting to a server, then all that initialization would take place when the script loads, instead of when the child object is instantiated.

Another way to deal with this is to differentiate in the constructor whether it is being called for inheritance (to assign to a prototype) or just to instantiate, and then not do the initialization stuff if it is being called for inheritance. But I prefer to just not call the constructor when inheriting, and so use an empty function for the constructor when inheriting.

I'm not very good at explaining this stuff. I recommend Crockford's site and also these two articles on Javascript inheritance.

CEL
+1  A: 

You actually only have to set the actual object's prototype, to a new instance of the baseConstructor:

Object.prototype.inherit = function(baseConstructor) {
  this.prototype = new baseConstructor();
};

I also suggest you to give a look to this Prototypal Inheritance technique that I found very clean.

CMS