2012-05-31 21 views
8

Si tengo una función de constructor de JavaScript, y configuro un método de destrucción en su prototipo. ¿Es posible eliminar (o al menos desarmar) la instancia del método de destrucción? Aquí hay un ejemplo de lo que intento hacer.Cómo hacer que una instancia se elimine dentro de una función de prototipo es JavaScript

Klass.prototype = { 
    init: function() { 
    // do stuff 
    }, 
    destroy: function() { 
    // delete the instance  
    } 
}; 

k = new Klass 
k.destroy() 
console.log(k) // I want this to be undefined 

entiendo que no puedo simplemente hacer this = undefined de con el método de destruir, pero pensé que podría obtener en torno a que mediante el uso de un tiempo de espera de este modo:

destroy: function() { 
    var self = this; 
    setTimeout(function() { 
    self = undefined 
    }, 0) 
} 

pensé que la función de tiempo de espera Tendría acceso a la instancia a través del self desde el cierre (y lo hace), pero eso no parece funcionar. Si yo console.log(self) desde el interior de esa función aparece como undefined, pero k en el alcance global sigue siendo una instancia de Klass.

¿Alguien sabe cómo hacer esto?

+0

¿Puedo preguntarle por qué necesita 'destruir' una instancia como esta? responder a la pregunta que hizo es una cosa pero puede que no le ayude a hacer lo que está tratando de hacer, por lo tanto, mi pregunta –

+0

JavaScript es basura recolectada y no tiene una forma explícita de destruir un objeto, por lo que no hay un lenguaje integrado para hacer lo que están preguntando. Al igual que con Pavel, tengo mucha curiosidad por saber por qué necesitas tal cosa, probablemente haya una mejor manera de lograr lo que quieres hacer. – chuckj

+0

Es para un plugin jQuery. Tener un método de destrucción parece más intuitivo que esperar que los desarrolladores eliminen o desactiven sus propias instancias, pero tal vez no sea así. –

Respuesta

3

k es una referencia que apunta a una instancia de Klass. cuando llama al destroy como un método de Klass, el this dentro de la función se une al objeto que llamó un método destroy. Ahora es otra referencia a esa instancia de Klass. El self que cierras en ese pequeño cierre es otra referencia más a esa instancia. Cuando lo configura en undefined borra esa referencia, no la instancia detrás de ella. Realmente no puedes destroy esa instancia per se. Puede olvidar al respecto (establezca todas las referencias a undefined y no lo encontrará de nuevo) pero eso es todo lo que puede ir.

Dicho esto, cuéntenos qué quiere lograr con esto y estaremos encantados de ayudarle a encontrar una solución.

+0

Tienes razón, siempre me olvido de que la asignación de 'self = this' solo contiene una referencia a dónde' this' está en la memoria. Obviamente no funciona, gracias! –

0

Lo que estás tratando de hacer es imposible. Incluso si sobrescribe this, no afectará ninguna variable que contenga una referencia a esa instancia. Y al invocar una función en él, seguirá teniendo el this correcto.

Lo único que podría hacer es establecer una variable en su función destroy que hará que cualquier otra función genere una excepción cuando se le llame. Pero eso sería una mala idea, ya que ralentizaría las cosas (vale, eso es insignificante) y puedes simplemente poner en los documentos de tu clase que ya no se debe usar después de que se haya llamado al destroy().

0

Esto funciona, pero requiere que usted sabe cuál es el nombre de la variable a la que el new Klass() se instancia:

function Klass() {}; 

Klass.prototype = { 
    init: function() { 
    // 
    }, 
    destroy: function() { 
    // Delete the variable that references the instance of the constructor. 
    delete window.k; 
    } 
}; 

k = new Klass(); 
k.destroy(); 
console.log(k); 

Si la variable k se nombra cualquier otra cosa que no funciona:

// Won't work. 
u = new Klass(); 
u.destroy(); 

También asume que la variable local k está realmente en el ámbito global. Si estuviera dentro de una función, tampoco funcionaría. Por ejemplo:

// Won't work. 
var fn = function() { 
    k = new Klass(); 
    k.destroy(); 
}; 

Finalmente se asume un entorno de navegador para el objeto window.

+0

O puede pasar el nombre de var a través de un parámetro 'destroy (ref);' y evaluar el código si es necesario. –

+0

¿y si tuviera 'a = k' justo antes de' k.destroy() '? Asumiría que 'a' todavía estará allí haciendo referencia a esa instancia –

+0

@PavelVeller que es exactamente correcta. No estoy proponiendo que esta sea una solución robusta en absoluto. –

1

Aunque es posible eliminar su propia instancia de objeto, es muy hortera. Es posible que desee consultar el artículo this.

Cuestiones relacionadas