6

I'm new to JavaScript programming and I am having a bit of a nightmare with inheritance. I am writing some code for Appcelerator Titanium and I have a base class called Slide2D that I wish to inherit from.

So I have placed a few functions in Slide2D's prototype. These are generally not going to be overwritten, but will be called from classes derived from Slide2D. These functions will also be called from other parts of the program. There are also various eventhandlers used to manage animation in Titanium.

If I make a couple of these slides in some calling code (using new)

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

all of my prototype methods point to the last Slide2D created, regardless of whether I use s or t. So 'slide2' will always be displayed, even if I'm using the s variable.

This is driving me mad - any help would be greatly appreciated.

Sorry for the length of the code but here it is:

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

Edit

Thanks very much for your prompt reply. I have made the changes that you recommended and that has resolved that particular problem.

However, a new issue has been introduced.

I need to call Slide2D.prototype.getView from a derived class - ExtendedSlide2D.

However, now I get the following error :

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

This is where I add the button to the base class's view object.

I'm sure this error just comes down to my inexperience with the language but, once again, any help would be greatly appreciated.

Once again - here is the code for 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();
4

1 回答 1

2

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

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

下面,我将你所有的“vars”强制替换为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;
};
于 2011-02-28T07:49:37.230 回答