0

I am trying to create a simple animation that makes a car image most across the screen (learning exercise). I am trying to make it happen with setInterval, and this doesn't seem to be working. The image is stationary. See code below:

var Car = function(x, y) {
  this.x = x;
  this.y = y;
};

Car.prototype.draw = function() {
  var carHtml = '<img src="http://nostarch.com/images/car.png">';

Car.prototype.moveRight = function(distance) {
  this.x;

  this.carElement.css({
    left: distance,
    top: this.y
  });
};

var tesla = new Car(20, 20);
tesla.draw();

function runOnInterval(fn, arg) {
  setInterval(function () {
    fn(arg);
  }, 1000);
}

runOnInterval(tesla.moveRight(), 10);

As I said, this results in the image being stationary, and an error message in the console saying "fn is not a function". Can anyone tell me what I am missing here? Thank you.

  • you are passing the result of calling a function `tesla.moveRight()` as `fn` .... you need to pass the function itself `tesla.moveRight` (you'll also probably have a `this` issue I'm guessing, depends if you know what you are doing) – Jaromanda X May 30 '18 at 23:41

1 Answers1

2

Arguments are evaluated eagerly. If you have foo(bar()) then bar is called first and its return value is passed to foo.

That's what happens in

runOnInterval(tesla.moveRight(), 10);

It calls tesla.moveRight() and passes the return value (undefined) to runOnInterval which will then error because undefined is not a function.

You have to pass tesla.moveRight itself and if you have to bind its this value to the correct object:

runOnInterval(tesla.moveRight.bind(tesla), 10);
// or
runOnInterval(function(x) { tesla.moveRight(x); }, 10);

See also:

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143