1

I use library supporting canvas drawing (easelJS) and i am still new to javascript. This library uses following 'class' hierarchy:

-DisplayObject

---Container

---Shape

---Bitmap

Now, all i want is to implement some additional functionality like simple physics engine. I want all of DisplayObjects (and descendants like container) to have it's own instances of additional properties, like for example velocity

When i try:

DisplayObject.prototype.velocity = new Vector2d();

It seems all instances share same velocity, even if later in my code I make assignmets like:

someShape.velocity.x = newValueX;    
someShape.velocity.y = newValueY;

I know some solutions of this problem but its not satisfying for me:

  1. I can make lots of classes like: MyShape (extending Shape), MyContainer(extending Container) etc, and in their constructur functions I can put this.velocity = new Vector2d();

  2. I can edit constructor of DisplayObject after downloading it, right in the library file (awful solution!)

  3. I can remember to add this properties in runtime right after object creation (even more awful!) someShape = new Shape() someShape.velocity = new Vector2d(); // 15 other properties here

  4. Or i can add function to the prototype of DisplayObject DisplayObject.prototype.exdendWithAdditionalProperties = new function(){ this.velocity = new Vector2d(); // 15 other properties here } which i will still need to remember to call manually after object creation.

But it seems to lot of work to me and i believe javascript can provide better solution.

Please help!

Przemek B
  • 125
  • 8

2 Answers2

1

It's not really an answer but keep in mind that in JS, the prototype and constructor are kind of special cases.

The prototype the parent object in the object chain. When you call a constructor, it will create a new object using the actual prototype.

But all of this isn't exactly necessary, you can do things like this:

function CustomShape() {
    var obj = new DisplayObject();
    obj.velocity = new Vector2d();
    return obj;
}

If you want to get fancy, you can use this solution to pass more parameters to the constructor:

https://stackoverflow.com/a/3362623/54606

It's hard to say more since we don't know exactly what you need. But check this out (Object.create)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create].

You could do something like this:

function MyCustomShape() {
   var obj = Object.create(DisplayObject.prototype);
   // more construction
   obj.velocity = new Vector2d();
   return obj;
}

The difference with the previous function is that this one never call the DisplayObject constructor. You'll have to either do that on your own or call the constructor with .apply or .call and some arguments.

Community
  • 1
  • 1
Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99
0

The problem with

DisplayObject.prototype.velocity = new Vector2d();

is that, if a DisplayObject instance doesn't have an own velocity property, it will inherit that one from the prototype.

And when you use

someShape.velocity.x = newValueX;
someShape.velocity.y = newValueY;

you are only altering that prototype one.

Instead, you could use

someShape.velocity = new Vector2d();
someShape.velocity.x = newValueX;
someShape.velocity.y = newValueY;

But I would do it inside the constructor:

this.velocity = new Vector2d();
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • But those are not my classes, those are from library, i cant just download them and edit constructors (i can but i find it very dirty workaround) – Przemek B May 08 '14 at 15:32