0

PROBLEM: When inheriting an object's properties and methods, a child object seems to loose connection with parent's 'this'. To illustrate it better, look at my example:

function RigidBody() {
    this.local = new Matrix4x3();
    this.position = new vec3();
    ...
}

RigidBody.prototype = {
    ...
    setPosition: function(vec) {
        this.position.copy(vec);
        this.local.setTranslation(this.position);
    }
    ...
};

CameraObject.prototype = new RigidBody();
CameraObject.prototype.constructor = CameraObject;

function CameraObject() {
    this.fov = ...
}

CameraObject.prototype.add = ...;

var camera = new CameraObject();
camera.add(...); // Works fine;
camera.setTranslation(...); // Throws "TypeError: Cannot read property 'setTranslation' of undefined
// And on another PC it throws: "http://localhost:8080/js/rigidBody.js(61): Uncaught exception: TypeError: Cannot convert 'this.local' to object"

How to bypass it? I found a workaround for this problem by assigning this.this = this; to parental object and replacing every this by this.this. Unfortunately as a result I need to add .this to every camera function call like this: camera.this.setPosition(...);

2 Answers2

0

as a general advice, please add console.log(camera) to your code and inspect the object in a good browser console, I highly recommend Firebug

that way you can explore what properties and nested properties are available to camera object

 


from your code example in original question, setTranslation appears to be a property of camera.local, not camera itself.

or perhaps you wanted to call camera.setPosition(...); given that you added it to RigidBody's prototype, but never used it afterwards - jsfiddle?


and given the code provided in comment below:

function Matrix4x3(){
    this.element = new Float32Array(16);
}

which does not define setTranslation, so this.local.setTranslation might be undefined as well..

Aprillion
  • 21,510
  • 5
  • 55
  • 89
  • Camera by itself does not contain `.local`, I'd like to treat it as an extension to `RigidBody` object, and because of this, it does not contain `setPosition` too. So by inheriting `RigidBody` object by any other object will allow me to manipulate this object in a 3D world. – Martin Winged May 28 '14 at 08:48
  • not sure what's your definition of *"itelf"*, but `camera`'s prototype DOES contain both `local` and `setPosition` - that is the whole point of prototypes and inheritance, that the object has access to all the properties of its prototype and inherited prototype, ... – Aprillion May 28 '14 at 10:06
  • I meant that `CameraObject` by itself does not contains `.local` before inheriting it from `RigidBody`. Anyway you are absolutely right, and now I'm like "WTF, why in my case it is not working properly?!" BTW for me it looks like after inheriting `RigidBody`, its inherited prototypes still tries to use it's original parent properties (look at the last line of my main post here which I added recently, maybe it would be a new hint) – Martin Winged May 28 '14 at 10:17
  • I believe `Matrix4x3` might not be a proper constructor or it might return some funny value instead of an object?? – Aprillion May 28 '14 at 10:27
  • When I manually merge those two objects, it works flawlessly, so I believe that the problem does not lie in those kind of things. Anyway this is what `Matrix4x3` look like: [img](http://screenshooter.net/0277897/xemmaan) – Martin Winged May 28 '14 at 10:57
  • i see, it looks as if you had no idea which methods are available to `camera`, which to `camera.local` and so on.. please use a proper IDE which will display available properties or a debugging tool like Firebug.. – Aprillion May 28 '14 at 11:17
  • `setTranslation` is a prototype of `Matrix4x3`, but I didn't show it on a picture, because there are lots of prototypes in there. `Float32Array` is just a native JavaScript array object, which is use in my case in WebGL app. Also, thanks for the Firebug recommendation, I will surely use it to debug my problem. BTW just before a moment I created an another object and in it's case inheritance works without any problems. So I guess that the 'CameraObject' is not well constructed. BTW2 is it possible to object have a proto which by itself uses `this.local`, but will inherit later? – Martin Winged May 28 '14 at 11:43
  • 1
    Ok, I found the problem - somewhere in `CameraObject` code I have created an array of `local`'s (in order to support multiple cameras, but instead of assigning old `local`'s to the array cell, I have assigned it to the whole array, like this: `this.inactiveLocals = []; this.inactiveLocals = new Matrix4x3();` Firebug is awesome ;] – Martin Winged May 28 '14 at 12:05
-1

You need to call "super", in other words, inherit the properties from the parent constructor:

function CameraObject() {
    RigidBody.call(this); // inherit RigidBody properties
    this.fov = ...
}
elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • When I call 'super' that way, the problem don't disappear, but strangely, now it throws an error one line earlier: "TypeError: Cannot read property 'copy' of undefined" – Martin Winged May 26 '14 at 09:11
  • you don't need to call any "super" when using prototypical inheritance - see comparison of calling super and prototypes in http://stackoverflow.com/a/13167725/1176601,, and e.g. http://jsfiddle.net/deathApril/AJch3/1/ applied to original question code – Aprillion May 28 '14 at 10:22