使用原型时的Javascript继承问题 - 实例被覆盖:(

时间:2011-02-28 07:06:56

标签: javascript class prototype appcelerator prototypal-inheritance

我是JavaScript编程的新手,我对继承有点噩梦。我正在为Appcelerator Titanium编写一些代码,我有一个名为Slide2D的基类,我希望继承它。

所以我在Slide2D的原型中放了一些函数。这些通常不会被覆盖,但会从Slide2D派生的类中调用。这些函数也将从程序的其他部分调用。还有各种用于在Titanium中管理动画的事件处理程序。

如果我在一些调用代码中使用这些幻灯片(使用新的)

var s = new Slide2D('slide1', 'background1.png', etc......
var t = new Slide2D('slide2', 'background2.png', etc......

我的所有原型方法都指向最后创建的Slide2D,无论我是使用s还是t。因此,即使我使用的是s变量,也会始终显示'slide2'。

这让我很生气 - 任何帮助都会非常感激。

对不起代码的长度,但这里是:

function Slide2D(name, backgroundImage, transform, inAnimation, outAnimation)
{
Titanium.API.info('Slide2D - Constructor - ' + name);

var _self = this;

var _name = name;

var _backgroundImage = backgroundImage;

var _startingTransform = transform;

var _slideView = Titanium.UI.createView({
    backgroundImage: _backgroundImage,
    transform: transform
});

    var _animateInAnimation = Titanium.UI.createAnimation();
_animateInAnimation.transform = Titanium.UI.create2DMatrix().translate(0,0);
_animateInAnimation.duration = 750;

var _animateOutAnimation = Titanium.UI.createAnimation();
_animateOutAnimation.transform = Titanium.UI.create2DMatrix().translate(-1024,0);
_animateOutAnimation.duration = 750;

var onAnimateInStart = function()
{
    Titanium.API.info('Slide2D.onAnimateInStart');
    Titanium.App.fireEvent('animateInStart', {slideName: _name});

    _animateInAnimation.removeEventListener('start', onAnimateInStart);
};

var onAnimateOutStart = function()
{
    Titanium.API.info('Slide2D.onAnimateOutStart');
    Titanium.App.fireEvent('animateOutStart', {slideName: _name});

    _animateInAnimation.removeEventListener('start', onAnimateOutStart);
};

var onAnimateInComplete = function()
{
    Titanium.API.info('Slide2D.onAnimateInComplete');
    Titanium.App.fireEvent('animateInComplete', {slideName: _name});

    _animateInAnimation.removeEventListener('complete', onAnimateInComplete);
};

var onAnimateOutComplete = function()
{
    Titanium.API.info('Slide2D.onAnimateOutComplete');
    Titanium.App.fireEvent('animateOutComplete', {slideName: _name});

    _animateOutAnimation.removeEventListener('complete', onAnimateOutComplete);
};

_animateInAnimation.addEventListener('start', onAnimateInStart);
_animateOutAnimation.addEventListener('start', onAnimateOutStart);

_animateInAnimation.addEventListener('complete',onAnimateInComplete);
_animateOutAnimation.addEventListener('complete', onAnimateOutComplete);

Slide2D.prototype.animateIn = function(){
    Titanium.API.info('Slide2D.prototype.animateIn - ' + _name);

    _slideView.animate(_animateInAnimation);
};

Slide2D.prototype.animateOut = function(){
    Titanium.API.info('Slide2D.prototype.animateOut');

    _slideView.animate(_animateOutAnimation);
};

    Slide2D.prototype.getName = function()
{
    return _name;
};

Slide2D.prototype.getView = function(){
    Titanium.API.info('Slide2D.prototype.getView');
    return _slideView;
};

Slide2D.prototype.getStartingTransform = function(){
    return _startingTransform;
};
 };

修改

非常感谢您的及时回复。我已经进行了您推荐的更改并解决了该特定问题。

但是,引入了一个新问题。

我需要从派生类 - ExtendedSlide2D调用Slide2D.prototype.getView。

但是,现在我收到以下错误:

Result of expression 'Slide2D.prototype.getView()' [undefined] is not an object
   at ExtendedSlide2D.js at line .......

这是我将按钮添加到基类的视图对象的位置。

我确定这个错误只是由于我对语言的经验不足,但是,再一次,任何帮助都会非常感激。

再一次 - 这是ExtendedSlide2D的代码:

Titanium.include('Slide2D.js');



function ExtendedSlide2D(name, backgroundImage, transform, inAnimation, outAnimation)
{

Titanium.API.info('ExtendedSlide2D - Constructor');


this.base = new Slide2D(name, 
                            backgroundImage, 
                            transform, 
                            inAnimation,     
                            outAnimation);



ExtendedSlide2D.prototype.constructor = ExtendedSlide2D;



var button = Titanium.UI.createButton({title: 'AnimateOut',
                                           height: 40,
                                           width: 200,
                                           top: 50

});

button.addEventListener('click', function()

{
    Slide2D.prototype.animateOut();

});


Slide2D.prototype.getView().add(button);
}



ExtendedSlide2D.prototype = new Slide2D();

1 个答案:

答案 0 :(得分:2)

您需要在Slide2D构造函数之外移动添加到原型的方法。这样,它们只被定义一次而不是每个对象实例化。

然后让那些原型函数访问“内部”,例如_name,_slideView等......您需要将所有“变量”(当前在闭包下可访问)转换为对象本身的属性。然后使用“this”引用所有这些成员属性。前缀。

下面,我粗暴地将所有“变量”替换为this.properties。只需要从原型方法访问的属性和函数需要进行此转换。对于内部函数(例如动画函数),它们仍然可以使用在闭包下可访问的变量。

function Slide2D(name, backgroundImage, transform, inAnimation, outAnimation) {

    Titanium.API.info('Slide2D - Constructor - ' + name);

    _self = this;

    this._name = name;

    this._backgroundImage = backgroundImage;

    this._startingTransform = transform;

    this._slideView = Titanium.UI.createView({
        backgroundImage: this._backgroundImage,
        transform: transform
    });

    this._animateInAnimation = Titanium.UI.createAnimation();
    this._animateInAnimation.transform = Titanium.UI.create2DMatrix().translate(0, 0);
    this._animateInAnimation.duration = 750;

    /// ...

};

Slide2D.prototype.animateIn = function () {
    Titanium.API.info('Slide2D.prototype.animateIn - ' + this._name);

    this._slideView.animate(this._animateInAnimation);
};

Slide2D.prototype.animateOut = function () {
    Titanium.API.info('Slide2D.prototype.animateOut');

    this._slideView.animate(this._animateOutAnimation);
};

Slide2D.prototype.getName = function () {
    this._name;
};

Slide2D.prototype.getView = function () {
    Titanium.API.info('Slide2D.prototype.getView');
    this._slideView;
};

Slide2D.prototype.getStartingTransform = function () {
    this._startingTransform;
};