Проблема наследования Javascript при использовании прототипов - экземпляры перезаписываются :(

Я новичок в программировании на 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. Таким образом, «слайд2» всегда будет отображаться, даже если я использую переменную s.

Это сводит меня с ума - любая помощь будет принята с благодарностью.

Извините за длину кода, но вот он:

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

Изменить

Большое спасибо за ваш быстрый ответ. Я внес изменения, которые вы рекомендовали, и это решило эту конкретную проблему.

Однако появилась новая проблема.

Мне нужно вызвать Slide2D.prototype.getView из производного класса — ExtendedSlide2D.

Однако теперь я получаю следующую ошибку:

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();

person Martin    schedule 28.02.2011    source источник
comment
Я объединил ваш ответ с вашим вопросом и удалил дубликаты вашей учетной записи. Пожалуйста, рассмотрите возможность привязки OpenID к вашей учетной записи или регистрации.   -  person Tim Post♦    schedule 28.02.2011


Ответы (1)


Вам нужно будет переместить методы, которые вы добавляете в прототип, за пределы функции конструктора 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;
};
person selbie    schedule 28.02.2011