Finalizar una instancia

En el este ejemplo podemos ver un primer intento de eliminar una instancia.


var ClassA = Class.create("ClassA", function (){
	this.value = "";
	this.$$DEFINE_STATIC = function(){
		this.$$static.instances = [];
	};
	this.$$constructor = function(v){
		this.$$static.instances.push(this);
		this.value = v;
	};
});

var inst = new ClassA("instance 1");
alert(inst.value);//instance 1
inst = null;
alert(ClassA.$$static.instances[0].value);//instance 1

Aunque a inst le hemos asignado null, no hemos eliminado la instancia que sigue manteniéndose intacta en ClassA.$$static.instances[0].
Para solventar este problema dispones de los métodos $$finalize y el atributo $$finalized en las instancias, y el método finalize de Class.
El método $$finalize lo tenemos que declarar dentro de la clase, dentro escribiremos las sentencias que nos permitan evitar cualquier error que suponga la finalización de la instancia.
Al método finalize de Class le enviaremos como argumento la instancia que queremos finalizar, este método primero ejecuta $$finalize y elimina todo los métodos y atributos menos $$finalized, cuyo valor será true y por último devuelve null.

Lo podemos ver en el siguiente ejemplo.


function ClassA(){
	this.value = "";
	this.$$DEFINE_STATIC = function(){
		this.$$static.instances = [];
		this.$$static.removeInstance = function(inst){
			var instances = this.$$static.instances;
			for(var ctr = 0; ctr < instances.length; ctr++){
				if(instances[ctr] == inst){
					instances.splice(ctr,1);
					break
				}
			}
		};
	};
	this.$$constructor = function(v){
		this.$$static.instances.push(this);
		this.value = v;
	};
	this.$$finalize = function(){
		this.$$static.removeInstance(this);
	};
};

var instances = [];
var ClassA = Class.create("ClassA",ClassA);
var inst1 = new ClassA("instance 1");
var inst2 = new ClassA("instance 2");
//almacenamos las intancias en el array
instances.push(inst1);
instances.push(inst2);
// finalizamos la instancia, ejecuta el método $$finalize
inst1 = Class.finalize(inst1);
alert(ClassA.$$static.instances.length)// 1

for(var ctr = 0; ctr < instances.length; ctr++){
	// si ha sido finalizada la instancia la eliminamos
	if(instances[ctr].$$finalized){
		instances.splice(ctr,1);
		ctr--;
	}
	else{
		alert(instances[ctr].value);////instance 2
	}
}

Otra cosa a tener encuesta es que los métodos y atributos añadidos mediante implement no pueden ser eliminados, pero se les asignaran el valor null.


var ClassX = Class.create("ClassX",function(){
	this.X = "X";
	this.getX = function(){
		return this.X;
	};
});

var ClassA = Class.create("ClassA",function(){
	this.$$implement(ClassX);
	this.value = "";
	this.$$constructor = function(v){
		this.value = v;
	};	
});

var ClassB = Class.extend("ClassB",ClassA,function(){
	this.$$constructor = this.$$super[0].$$constructor;
});

ClassB.implement({
     proto:"proto"
});


var instB = new ClassB("instance B");
document.write("PROPERTIES".bold() +  "<br>");
for(var prop in instB) document.write("" +  prop + "<br>");
Class.finalize(instB);
for(var prop in instB) alert(prop);
/*
proto
$$finalized
*/