访问变量

时间:2011-07-01 16:02:40

标签: javascript jquery

当我在positionSlides方法上执行控制台跟踪时,它将slideShow显示为undefined。 当我在document.ready回调中清楚地实例化它时,这怎么可能呢?我还确保将此变量设为全局变量,因此slideShow和slideShowNavigation都可以访问这两个变量。

var slideShow, slideShowNavigation;

    $(document).ready(function(){

        slideShow = new SlideShow( $('#header #slideshow'), 980 );
        slideShowNavigation = new SlideShowNavigation( $('#header').find("#leftArrow"), $('#header').find("#rightArrow") );

    });


    // SLIDE SHOW CLASS
    function SlideShow( divContainer, slideWidth ){
        // Check to make sure a new instance is created
        if( ! (this instanceof SlideShow) ) return new SlideShow();

        this.$imageContainer = divContainer;
        this.slideWidth = slideWidth;
        var maxImages =     this.$imageContainer.children().length;

        this.getMaxSlides = function(){
            return maxImages;
        }

        this.positionSlides();

    }

    SlideShow.prototype.positionSlides = function(){
        console.log('imageContainer = '+slideShow);
    }

    SlideShow.prototype.update = function( dir ){

    }


    // ARROW NAVIGATION FOR SLIDESHOW

    function SlideShowNavigation( left, right){
        if( ! (this instanceof SlideShowNavigation) ) return new SlideShowNavigation();

        //this.updateArrows( slideShow.$imageContainer.find(":first") );

    }

    SlideShowNavigation.prototype.updateArrows = function( item ){

    }

5 个答案:

答案 0 :(得分:0)

您已从Slideshow构造函数调用positionSlides。在构造函数完成之后才会设置slideShow变量。所以,在locationSlides的这一部分设置之前,你正在访问slideShow全局变量:

console.log('imageContainer = '+slideShow);

我建议在positionSlides方法中,你可以引用“this”而不是全局变量。

将该行更改为:

console.log('imageContainer = ' + this);

作为一个建议,我发现使用仅在slideShow(全局变量名称)和SlideShow(函数名称)和slideshow的情况下不同的变量名称有点危险(CSS标识符)。它使您的代码更难以阅读和理解,并且很容易在无意中犯错误。在这种情况下,我建议全局变量类似于“theSlideShow”,以提高可读性,减少错误发生的可能性。

答案 1 :(得分:0)

问题在于:

slideShow = new SlideShow( $('#header #slideshow'), 980 );

该行调用SlideShow函数,该函数调用positionSlides(),查找slideShow,但在SlideShow函数返回之前未定义slideShow。

相反,在positionSlides()中使用this而不是slideShow来引用实例(这样你的类就独立于变量名。

答案 2 :(得分:0)

slideShow函数返回该定义之前,未定义

SlideShow。在构造函数完成之前调用SlideShow.positionSlides

修复:仅在positionSlides定义后调用slideShow

var slideShow, slideShowNavigation;

    $(document).ready(function(){

        slideShow = new SlideShow( $('#header #slideshow'), 980 );
        slideShow.positionSlides();
        slideShowNavigation = new SlideShowNavigation( $('#header').find("#leftArrow"), $('#header').find("#rightArrow") );

    });


    // SLIDE SHOW CLASS
    function SlideShow( divContainer, slideWidth ){
        // Check to make sure a new instance is created
        if( ! (this instanceof SlideShow) ) return new SlideShow();

        this.$imageContainer = divContainer;
        this.slideWidth = slideWidth;
        var maxImages =     this.$imageContainer.children().length;

        this.getMaxSlides = function(){
            return maxImages;
        }

    }

    SlideShow.prototype.positionSlides = function(){
        console.log('imageContainer = '+slideShow);
    }

    SlideShow.prototype.update = function( dir ){

    }


    // ARROW NAVIGATION FOR SLIDESHOW

    function SlideShowNavigation( left, right){
        if( ! (this instanceof SlideShowNavigation) ) return new SlideShowNavigation();

        //this.updateArrows( slideShow.$imageContainer.find(":first") );

    }

    SlideShowNavigation.prototype.updateArrows = function( item ){

    }

答案 3 :(得分:0)

SlideShow对象在其构造函数中调用方法positionSlides

this.positionSlides();

此方法尝试访问您要为其分配的变量:

console.log('imageContainer = '+slideShow);

它还不存在,因为构造函数还没有完成。

(编辑 - 关于两个对象之间关系的讨论)

SlideShow需要调用SlideShowNavigation的方法” - 使用Java中的事件完成。

您可以在javascript中使用回调来创建事件驱动模型。

假设SlideShowNavigation在导航中具有SlideShow对象的依赖关系。还要注意使用单个options对象参数而不是单个参数,这是一个常见的构造,因为它简化了参数传递,从而产生更易读,更易于维护的代码。如果你添加/删除一个参数,你不会冒险破坏某些东西,因为它们不依赖于这种方式。

function SlideShow() {
   // setup code

   this.onSomethingHappened=null;
}
SlideShow.prototype.doSomething() {
    // do something

    /// if a callback exists & is defined properly, then invoke it
    if (this.onSomethingHappened && 
            typeof this.onSomethingHappened==='function') {
        this.onSomethingHappened(this);
    }
}
SlideShow.prototype.publicMethod() {

}

function SlideShowNavigation(options){
    if( ! (this instanceof SlideShowNavigation) ) 
        return new SlideShowNavigation();

    this.slideShow = options.slideShow
    this.left = options.left;
    this.right = options.right;

    // bind to callbacks (events): assigning the `onSomethingHappened` property
    // of the SlideShow to a function in this object, which it will call at the
    // appropriate time

    this.slideShow.onSomethingHappened = this._somethingHappened;

     //this.updateArrows( slideShow.$imageContainer.find(":first") );

}

// i use an underscore to indicate a private method - since there's
// no way to create non-public prototype members. You can can 
// alternatively create private functions in the constructor though
// it's less memory efficient, and they are not directly accessible
// from prototype methods.

SlideShowNavigation.prototype._somethingHappened(e) {
    // e is the sender of the event
    ...
    // you can invoke methods of the sender directly using the ref passed here, 
    // if you like
    e.publicMethod();
}

答案 4 :(得分:0)

问题在于您通过调用幻灯片功能来定义幻灯片放映。该函数调用positionSlides。在对象完成构造之前调用它。