6

Soy nuevo en la programación de JavaScript y estoy teniendo un poco de pesadilla con la herencia. Estoy escribiendo un código para Appcelerator Titanium y tengo una clase base llamada Slide2D que Deseo heredar de.Problema de herencia de Javascript al usar prototipos - instancias sobreescritas :(

Así que he colocado algunas funciones en el prototipo de Slide2D. Generalmente no se sobrescribirán, pero se llamarán desde clases derivadas de Slide2D. Estas funciones también se llamarán desde otras partes de el programa. También hay varios manejadores de eventos utilizados para administrar la animación en Titanio.

Si hago un par de estas diapositivas en algún código de llamada (usando nuevo)

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

todos mis métodos de prototipo apuntan a la última Slide2D creada, independientemente de si uso s o t. Entonces 'slide2' siempre se mostrará, incluso si estoy usando la variable s.

Esto me está volviendo loco - cualquier ayuda sería muy apreciada.

Lo siento por la longitud del código, pero aquí está:

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

Editar

Muchas gracias por su pronta respuesta. Realicé los cambios recomendados y eso resolvió ese problema en particular.

Sin embargo, se ha introducido un nuevo problema.

Necesito llamar a Slide2D.prototype.getView de una clase derivada - ExtendedSlide2D.

Sin embargo, ahora me sale el siguiente error:

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

Aquí es donde agrego el botón de vista de objetos de la clase base.

Estoy seguro de que este error se reduce a mi inexperiencia con el idioma, pero, una vez más, cualquier ayuda sería muy apreciada.

Una vez más - Este es el código para 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(); 
+0

He fusionado su respuesta con su pregunta y he eliminado la duplicación de su cuenta.Considere asociar un OpenID con su cuenta o registrarse. –

Respuesta

2

Tendrá que mover los métodos que se agregan al prototipo fuera de la función constructora Slide2D. De esta forma, solo se definen una vez en lugar de con cada instanciación de objetos.

Y luego para aquellas funciones de prototipo para acceder a las "partes internas", como _name, _slideView, etc ... Deberá convertir todos sus "vars" (actualmente accesibles bajo cierre) para que sean propiedades del objeto mismo . Luego haga referencia a todas las propiedades de miembros con un "esto". prefijo.

A continuación, he reemplazado brutalmente todos sus "vars" para que sean this.properties. Solo las propiedades y funciones a las que debe acceder desde los métodos prototipo necesitan esta conversión. Para las funciones internas (como las funciones animadas), es posible que aún puedan usar vars accesibles al cerrar.

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