2

This is my first time working with inheritance in Javascript. I have a classical parent-child relation between an object "LatchOn" that does one thing, and an object "LatchOnSlider" that has all the functionality of the base class and then some more. stripped down code:

/*creating the instances*/

var latchon = NewLatchOn();   //arguments not important for this
var latchonslider = NewLatchOnSlider();

//factory function
function NewLatchOn(element_id, container_id, screenpos, release)
{
 var newLatchOn = new LatchOn(element_id, container_id, screenpos, release);
 newLatchOn.startTimer();
}

function LatchOn(element_id, container_id, screenpos, release)
{
  //initialise stuff
}


LatchOn.prototype.startTimer = function()
{
 var that = this;     
 setInterval(function(){that.checkPos()}, 10);
}

LatchOn.prototype.checkPos = function()
{
    //do stuff
}






LatchOnSlider.prototype.constructor = LatchOnSlider;

//factory function
function NewLatchOnSlider(element_id, container_id, image_class, screenpos)
{
 LatchOnSlider.prototype = Object.create(LatchOn.prototype);
 var newSlider = new LatchOnSlider(element_id, container_id, image_class, screenpos);
 newSlider.startTimer();
 return newSlider;
}

function LatchOnSlider(element_id, container_id, image_class, screenpos)
{
 LatchOn.call(this, element_id, container_id, screenpos, "CONTAINER");
 
    //initialise own stuff
}


LatchOnSlider.prototype.startTimer = function()
{
 var that = this;     
 setInterval(function(){that.checkPos()}, 10);
}

/*keeps track of when to switch images*/
LatchOnSlider.prototype.checkPos = function()       
{
 alert("child process called");
}

The objects have to listen to the scrollposition in the browser and act according to that information. So they have a timer running. But as it wouldn't be optimal for two timers running for the inherited object, I figured I could just run one timer that calls the function on the child object, which will invoke the base function and then do its own stuff (invocation of base function not yet in the code. I haven't gotten that far yet...).

In order to not have to start the timer separately for every instance, I made factory functions to initialise the objects and start their timers. And this is where I'm stuck. No matter what I do, if I call startTimer on the LatchOnSlider object, the function of the parent gets called instead. I've looked through at least five different tutorials and tried all their syntax variations, but nothing fixes the problem. I've walked through it in firebug, the process works as expected up to that point. The constructor of LatchOnSlider gets called, the constructor of the base object gets called from there, everything initialises properly, just when LatchOnSlider.startTimer() is called, LatchOn.startTimer() gets executed instead. I'm pretty much out of ideas as to what might be the problem at this point.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
UncleBob
  • 1,233
  • 3
  • 15
  • 33
  • Everything I've looked up on this writes this line `LatchOnSlider.prototype = Object.create(LatchOn.prototype);` like this `LatchOnSlider.prototype = new LatchOn();` – Dan Apr 23 '15 at 18:36
  • @Dan: Then you should look somewhere else in the future… [Don't use `new Parent`](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here) – Bergi Apr 23 '15 at 18:37
  • @Bergi http://stackoverflow.com/a/27642444/839501 – Dan Apr 23 '15 at 18:38
  • @Dan: Thanks, I've downvoted it :-) See HMRs comment – Bergi Apr 23 '15 at 18:42
  • One other observation I have is that most people define this,`LatchOnSlider.prototype = Object.create(LatchOn.prototype);` outside of a function. Usually just before the `LatchOnSlider.prototype.constructor = LatchOnSlider;` line. [here.](http://stackoverflow.com/a/16063711/839501) – Dan Apr 23 '15 at 18:53

1 Answers1

0

This line is the problem:

function NewLatchOnSlider(element_id, container_id, image_class, screenpos) {
  LatchOnSlider.prototype = Object.create(LatchOn.prototype);

Here, you are creating a new prototype object every time an instance is created. Those new prototypes do not have the methods you had assigned on the "old" LatchOnSlider.prototype before, and your instances will not inherit them - only the LatchOn.prototype methods indirectly.

You will need to keep the constructor declaration and the prototype initialisiation separate from your factory function:

function NewLatchOnSlider(element_id, container_id, image_class, screenpos) {
    var newSlider = new LatchOnSlider(element_id, container_id, image_class, screenpos);
    newSlider.startTimer();
    return newSlider;
}

function LatchOnSlider(element_id, container_id, image_class, screenpos) {
    LatchOn.call(this, element_id, container_id, screenpos, "CONTAINER");
    // initialise own stuff
}

LatchOnSlider.prototype = Object.create(LatchOn.prototype);
LatchOnSlider.prototype.constructor = LatchOnSlider;
LatchOnSlider.prototype.startTimer = function() { … }
LatchOnSlider.prototype.…

For assignments, order matters :-)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375