1

I Get an 'undefined' error when trying to run the following code. It happens on the line this.xPositionForPageAtIndex(selectedPageNumber). When I try to log this all of the instance properties are there, except the function.

function Gallery(div) {
    this.count = 5;
    this.pageWidth = 500;
    this.selectedPage = 1;

    this.xPositionForPageAtIndex = function(pageIndex) {
        if (pageIndex < 1 || pageIndex > this.count) {
            return 0.0;
        }

        return (pageIndex - 1) * this.pageWidth;
    }
}

Gallery.prototype = {
    set selectedPage(selectedPageNumber) {
        var page = this.pages[((selectedPageNumber) + 1)];

        if (!page.classList.contains("animate")) {
            page.classList.add("animate");
        }

        if (!page.classList.contains("final")) {
            page.classList.add("final");
        }

        console.log(this);

        this.binder.setAttribute("-webkit-transform", "translateX(" -this.xPositionForPageAtIndex(selectedPageNumber) + "px)");

        this.selectedPage = page;
    }
}

I am a little new to Javascript OOP, but I don't think I really know enough terminology to be able to properly research this answer.

9
  • Is this a special kind of JS?? Commented Jan 2, 2013 at 2:02
  • Its javascript object oriented programming Commented Jan 2, 2013 at 2:03
  • There should be a + before this.xPosition... on the line where you set the webkit attribute Commented Jan 2, 2013 at 2:04
  • I want to scroll the gallery from left to right, in order to do that the x position has to be negative. Commented Jan 2, 2013 at 2:05
  • 2
    anyone reading this who, like me, was puzzled by set might want to have a look at this ejohn.org/blog/javascript-getters-and-setters Commented Jan 2, 2013 at 2:09

1 Answer 1

1

Concat issue

On the line you said you were having trouble with had a minus instead of a plus:

"translateX(" -this.xPositionForPageAtIndex(selectedPageNumber)

should be

"translateX("  + this.xPositionForPageAtIndex(selectedPageNumber)

Optimize by putting public methods in the prototype

Also, it may be a good idea to put xPositionForPageAtIndex in the prototype as well, since it doesn't rely on any private fields. Any public function(which means it relies on no private fields) can go into the prototype. That way, there won't be a copy of the function for each instance of the object you're creating.

Based on your code, I don't think you'll have enough Gallery instances for this to be a problem, but it's good practice nonetheless.

On the other hand, if your function relies on some sort of private field, that means it's a privileged function, and it cannot go into the prototype. Something like this:

function Gallery(someParam){
    //this is a private variable
    var hiddenVar = someParam + "bar";

    // this is a privileged method: publicly accessible, but
    // can "see" private variables
    this.showHidden = function() {
        return hiddenVar
    };      
};
var gal = new Gallery("foo");
gal.hiddenVar; // undefined
gal.showHidden(); // "foobar"

Unintended infinite recursion

A bigger problem is the following line:

this.selectedPage = page;

that line is within the setter for the property selectedPage.

That line makes selectedPage recursively call itself, and can only end in a RangeError.

Writing it in terms of functions makes it a little more clear, so here is what's happening:

var a = {
    foo: function(param){
        // do some stuff
        this.foo(4);
    }
};

calling a.foo(2) will result in a RangeError.

It's hidden a bit, because of the way ES5 setters work. Here's what that would look like using setters:

var a = {
    set foo(){
        // do some stuff
        this.foo = 3;
    }
};

calling a.foo = 2 will result in a RangeError because the setter function is being called recursively.

Hope that helps a bit. If you haven't checked out Douglas Crockford yet, youtube him. There are some good lectures that may help you out quite a bit.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.