Javascript 原型 属性 在函数中返回未定义

Javascript prototype property returning undefined in function

使用原型继承创建图像旋转器,我不断在控制台中收到错误显示:TypeError: this.curPhoto is undefined this.curPhoto.removeClass('previous'); 我把它放在用于切换重叠 div 位置的函数之一的回调函数中(彼此堆叠)这是代码:

    <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
    <script src='ImageRotatorOOP.js' type='text/javascript'> </script>
    <script type='text/javascript'>
    $('document').ready(function() {
    setInterval('rotateImages()', 2000);
    });

    function rotateImages() {
    var imageRotator = new ImageRotator($('#photoShow'));
    if(imageRotator.nextPhoto.length == 0) {
        imageRotator.nextPhoto = imageRotator.container.children().first();
    }

    imageRotator.stackImages();
    }
    </script>

    </head>
  <body>
  <h1> Image Rotator </h1>
  <div id='photoShow'>
<div class='current'>
    <img src='images/RoyMustang.jpg' alt='Roy Mustang' />
</div>
<div>
    <img src='images/nhk.png' alt='Welcome to the NHK' />
</div>
<div>
    <img src='images/dragonball_z.jpg' alt='Dragonball Z'/>
</div>
</div>
</body>
</html>

和 .js 文件

    var ImageRotator = function(container) {
this.container = container;
this.curPhoto = this.container.find('div.current');
this.nextPhoto = this.curPhoto.next('div'); 
}

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        this.curPhoto.removeClass('previous');
    });
}

这是 css 文件

   #photoShow img {
    width: 400px;
    height: 300px;  
    }

    #photoShow div {
    position: absolute;
    z-index: 0;
    }

    #photoShow div.previous {
    z-index: 1;
    }

    #photoShow div.current {
    z-index: 2;
    }

在动画完成函数中,this 的值将是正在动画的 DOM 对象,而不是您的 ImageRotator 对象。您可以通过执行以下操作来解决该问题:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    var self = this;
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000, function() {
        self.curPhoto.removeClass('previous');
    });
}

注意:这是回调函数的常见问题,因为 Javascript 中的每个函数调用都会为 this 设置一个新值,因此除非动画回调专门设计用于设置 this 到你想要的,它会被设置成别的东西。在嵌入回调之前将值保存到局部变量是一种常见的解决方法。您也可以使用 .bind() 来做类似的事情,但它是为您做的。

这是一个使用 .bind() 的例子:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000, function() {
        this.curPhoto.removeClass('previous');
    }.bind(this));
}

问题出在这段代码中:

ImageRotator.prototype.stackImages = function() {
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        this.curPhoto.removeClass('previous');
    });
}

在线上,this.curPhoto.removeClass('previous');this 不是指 ImageRotator 实例,而是指 jQuery 对象。

您可以通过在上面的闭包中保存 this 的值来解决这个问题。

ImageRotator.prototype.stackImages = function() {
    var that = this;
    this.curPhoto.removeClass('current').addClass('previous');
    this.nextPhoto.css({opacity: 0.0}).addClass('current').animate({opacity: 1.0}, 1000,      function() {
        that.curPhoto.removeClass('previous');
    });
}