1

尝试运行以下代码时出现“未定义”错误。它发生就行了this.xPositionForPageAtIndex(selectedPageNumber)。当我尝试记录this所有实例属性时,除了函数。

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;
    }
}

我对 Javascript OOP 有点陌生,但我认为我真的不知道足够多的术语来正确研究这个答案。

4

1 回答 1

1

连续问题

在你说你遇到麻烦的那一行是减号而不是加号:

"translateX(" -this.xPositionForPageAtIndex(selectedPageNumber)

应该

"translateX("  + this.xPositionForPageAtIndex(selectedPageNumber)

通过将公共方法放在原型中进行优化

此外,放入xPositionForPageAtIndex原型可能也是一个好主意,因为它不依赖任何私有字段。任何公共函数(这意味着它不依赖于私有字段)都可以进入原型。这样,您正在创建的对象的每个实例都不会有该函数的副本。

根据您的代码,我认为您不会有足够的Gallery实例来解决这个问题,但这是一个很好的做法。

另一方面,如果你的函数依赖于某种私有字段,那意味着它是一个特权函数,它不能进入​​原型。像这样的东西:

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"

意外的无限递归

更大的问题是以下行:

this.selectedPage = page;

该行在属性的设置器内selectedPage

该行selectedPage递归调用自身,并且只能以RangeError.

用函数来写它会更清楚一点,所以这就是正在发生的事情:

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

调用a.foo(2)将导致一个RangeError.

由于 ES5 设置器的工作方式,它被隐藏了一点。下面是使用 setter 的样子:

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

调用a.foo = 2 将导致 aRangeError因为 setter 函数被递归调用。

希望那些对你有帮助。如果您还没有查看 Douglas Crockford,请在 YouTube 上观看他。有一些很好的讲座可以帮助你很多。

于 2013-01-02T05:26:07.780 回答