4

I need an array to store some geometrical data. I would like to simply inherit from the Array object and than extend it with a few new functions like "height" and "width" (sum of all children's heights/widths), but also with a few convenience methods like "insertAt" or "remove".

What is the best way to do it without modifying the original Array object (Array.prototype.myMethod)?

Piotr Zurek
  • 2,800
  • 2
  • 24
  • 32

3 Answers3

5

You can always mixin your changes directly into Array, but that might not be the best choice given that it's not something every array should have. So let's inherit from Array:

// create a constructor for the class
function GeometricArray() {
   this.width = 0;
   this.height = 0;
}

// create a new instance for the prototype so you get all functionality 
// from it without adding features directly to Array.
GeometricArray.prototype = new Array();

// add our special methods to the prototype
GeometricArray.prototype.insertAt = function() {
  ...
};

GeometricArray.prototype.remove = function {
  ...
};

GeometricArray.prototype.add = function( child ) {
   this.push( child );
   // todo calculate child widths/heights
};
chubbsondubs
  • 37,646
  • 24
  • 106
  • 138
  • 1
    I'm sorry but it doesn't seem to work for me. That was my initial approach but somehow when I call any of the Array methods on the "GeometricArray" I get: "TypeError: Object # has no method 'push'" I'm pretty sure it's me doing something wrong though. :-) – Piotr Zurek Feb 17 '11 at 03:02
  • @piotr I demonstrated the same technique earlier today. Maybe another example will help: http://stackoverflow.com/questions/5020954/adding-functions-to-javascripts-array-class-breaks-for-loops/5021375#5021375 – Wayne Feb 17 '11 at 03:36
  • I'll definitely try playing with it again on a simpler code than now to reduce a chance of something else screwing up the result. – Piotr Zurek Feb 17 '11 at 03:53
2

Are you (maybe) applying Java concepts to Javascript?

You don't need to inherit from classes in Javascript, you just enrich objects.

So the best way in my world (a world full of people head-butting methods into objects) is:

function GeometricArray()
{
  var obj=[]

  obj.height=function() {
    // wibbly-wobbly heighty things

    for(var i=0;i<this.length;i++) {
      // ...
    }

  }

  obj.width=function() {
    // wibbly-wobbly widy things
    // ...
  }

  // ...and on and on...

  return obj
}
ZJR
  • 9,308
  • 5
  • 31
  • 38
  • I have accepted the above answer as it was closer to what I have expected but this solution worked equally well. I would love to see someone explain pros and cons of both solutions. – Piotr Zurek Feb 25 '11 at 02:25
  • `prototype` and `this` are all part of a what the `new` operator does in javascript. It's an overthought with little to no point in existing as long as you are the one that writes the constructor. – ZJR Feb 25 '11 at 23:53
  • That is, unless you're enriching *Core* objects, like `Array` or `Object`. In that case you cannot override the constructor, but using `prototype` you can enrich those objects anyway. (only, it came out, it's really easy to shoot yourself in a foot this way) I'm not up to date on that, but I suppose some browser could treat enriching of some core objects like a security threat – ZJR Feb 25 '11 at 23:55
1

You could use prototyping to put those functions in Array.

To add the height function for example do this:

Array.prototype.height = function() {
    //implementation of height
}
Rian Schmits
  • 3,096
  • 3
  • 28
  • 44