Pregunta

Tengo una clase de Javascript que contiene algunas funciones y objetos miembro:

function MyUtils()
{
  // Member Variables (Constructor)
  var x = getComplexData();
  var y = doSomeInitialization();

  // Objects
  this.ParamHash = function()
  {
    // Member variables
    this.length = 0;
    this.items = new Array();

    // Constructor
    for (var i = 0; i < arguments.length; i += 2)
    {
      // Fill the items array.
      this.items[arguments[i]] = arguments[i+1];
      this.length++;
    }
  }

  // Functions
  this.doSomething = function()
  {
    // Do something.
    // Uses the items in the ParamHash object.
    for (var i in this.ParamHash.items)
    {
      // Really do something!
    }

    // Clear the ParamHash object -- How??
  }
}

Esta se invoca de la siguiente manera:

// First call - works fine.
var utils = new MyUtils();
utils.paramHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();

// Don't want to re-initialize.
// utils = new MyUtils();

// Consequent call - crashes ["Object doesn't support this action."].
utils.paramHash = new utils.ParamHash("c", 3);
utils.doSomething();

El problema surge de la restricción de que quiero volver a utilizar el mismo objeto utils durante todo el código sin tener que volver a iniciarlo. Además, quiero el objeto ParamHash se vuelva a crear a partir de cero cada vez que lo llamo. Sin embargo, las consiguientes llamadas al constructor ParamHash emiten un error "Objeto no admite esta acción." En esta etapa, puedo ver que el objeto utils.paramHash todavía contiene los valores antiguos ( "a", "b").

He intentado varios métodos para liberar el objeto ParamHash como por ejemplo definiendo la longitud y artículos en nulo, apareciendo elementos de la matriz. Nada parecía funcionar hasta que use la siguiente manera (en la función doSomething()):

this.paramHash.items = new Array();
this.paramHash.length = 0;

Esto parece mal porque lo que si tuviera una gran cantidad de variables miembro ... tendría que reiniciar cada uno de ellos de forma individual? Entonces, la pregunta es: ¿Cuál es la mejor manera de restablecer el objeto ParamHash al estado inicial? Estoy seguro de que la esperanza de que hay una manera directa limpiador / más. Algo así como:

// Doesn't work! :-(
this.paramHash = new function() {};

EDIT:. Estoy buscando una solución multi-navegador - Uno que funciona al menos en IE6 y FF + 2 +


Solución: Gracias a Cristoph, yo era capaz de hacerlo mediante la creación de una variable / propiedad separada dentro MyUtils que sólo posee la instancia de la función ParamHash

.
function MyUtils()
{
  // Same ol' stuff.
  var myParamHash;
}

// First call - works fine.
var utils = new MyUtils();
utils.myParamHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();

// Consequent call - works fine now.
utils.myParamHash = new utils.ParamHash("c", 3);
utils.doSomething();
¿Fue útil?

Solución

Este

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

sobrescribe el la propiedad que tiene la función de constructor ParamHash() con un objeto de instancia. Usted podría conseguir el constructor de vuelta a través

utils.ParamHash.constructor

pero la forma más limpia sería la de no sobrescribir en el primer lugar y el uso de una propiedad separada para mantener la instancia.


No sé el problema exacto Cerebrus está tratando de resolver, por lo que podría haber razones válidas para lo que está haciendo. Pero en mi opinión, la solución se complica demasiado. Me gustaría hacer algo como esto:

function MyUtils() {
    this.x = getComplexData();
    this.y = doSomeInitialization();
    this.params = {};
}

MyUtils.prototype.doSomething = function() {
    for(var prop in this.params) {
        if(this.params.hasOwnProperty(prop)) {
            // do stuff
        }
    }
};

var utils = new MyUtils;
utils.params = { a : 1, b : 2 };
utils.doSomething();

El cheque por hasOwnProperty() no es necesario si usted puede estar seguro de que nadie se metió con Object.prototype.


Algunos comentarios adicionales:

  • en JavaScript, normalmente sólo los nombres de las funciones constructoras se capitalizan
  • items no debe ser una matriz, pero un objeto liso, es decir, this.items = {};

Otros consejos

cuando se hizo esto

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

se ha sustituido la función constructora ParamHash con una instancia de objeto. new ParamHash() posterior falla porque utils.ParamHash ya no es una función constructora.

Prueba esto:

var utils = new MyUtils();
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
utils.DoSomething();

¿Has probado la omisión de la nueva palabra clave?

utils.ParamHash = utils.ParamHash("c", 3);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top