0

I am attempting to create an endless prototype function. Here is my attempt, which is not working:

function Cat(name, direction) {
this.name = name;
this.stand = {left: "images/standLeft.png", right: "images/standRight.png"};
this.walk = {left: "images/walkLeft.gif", right: "images/walkRight.gif"};
this.direction = direction;
}

Cat.prototype.walking = function() {
var myDirection = (this.direction == "right" ? "+=": "-=");
var myPosition = $("#cat").css("left");
myPosition = myPosition.substring(0, myPosition.length - 2);

var distanceLeft = myPosition;
var distanceRight = 1024 - myPosition - 173;


if(this.direction == "right") {
    var distance = distanceRight;
} else {
    var distance = distanceLeft;
}
    $("#cat img")[0].src =  this.walk[this.direction];
    $("#cat").animate({
        left: myDirection + distance
        }, (22.85 * distance), function(){
            this.direction = (this.direction == "right" ? "left": "right");
             this.walking();
        });
}

var myCat = new Cat("Izzy", "right");

I thought calling (this.walking()) would run the same function again with the same object, however it is throwing an error. Any thoughts or suggestions?

Qantas 94 Heavy
  • 14,790
  • 31
  • 61
  • 78

2 Answers2

1

this there will be window scope.

$("#cat img")[0].src =  this.walk[this.direction];
var that = this;
$("#cat").animate({
    left: myDirection + distance
    }, (22.85 * distance), function(){
        that.direction = (that.direction == "right" ? "left": "right");
         that.walking();
    });
epascarello
  • 185,306
  • 18
  • 175
  • 214
0

See my explanation of scope handling in JavaScript (and jQuery) on this StackOvervlow thread. In your case, you should just accept that jQuery will choose this to be something other than your cat object. Also note that jQuery works with a HTML element, not with an instance of cat, so even if it wanted to it couldn't set this = your cat object.

You can alleviate the problem by wrapping the function in $.proxy (link), like so:

// This is your original handler. I made this a named function for clarity.
var animateHandler = function() {
    this.direction = (this.direction == "right" ? "left": "right");
    this.walking();
}

// Now here's your original call to animate.
$("#cat").animate(
    { left: myDirection + distance},
    (22.85 * distance),
    animateHandler
);

// Here's what you'd change it to.
$("#cat").animate(
    { left: myDirection + distance },
    (22.85 * distance),
    $.proxy(animateHandler, this)
);
Community
  • 1
  • 1
Mihai Danila
  • 2,029
  • 1
  • 18
  • 24