2010-08-04 10 views
5

Tengo un Javascript que funciona y manipula algunos elementos DOM. El problema es que no entiendo por qué funciona, lo cual nunca es algo bueno. Estoy tratando de aprender más acerca de las prácticas recomendadas de javascript y javascript orientadas a objetos, por lo que la organización puede parecer un poco extraña.

Básicamente, envuelvo dos métodos que manipulan el DOM dentro de un objeto CSContent. Creo una instancia de ese objeto, content en $(document).ready y vinculo algunos eventos a las funciones en content. Sin embargo, no estoy seguro de cómo se pueden seguir llamando a estas funciones después de las salidas $(document).ready. ¿Eso no significa que content ha salido del alcance, y sus funciones no están disponibles? De todos modos, aquí está el código:

+0

¿Puede mostrar un ejemplo de dónde tiene acceso a 'content' donde no debería tener? –

+0

@Pekka: cuando en el elemento con id 'edit-cscontent-cs-content-tweet' se pulsa o presiona una tecla, por ejemplo? –

+0

@Marcel ahh, ¡eso es lo que quería decir! Eso es un cierre. Pero ya estás explicando eso en tu respuesta, sería +1 pero no tengo votos para hoy. –

Respuesta

2

supongo que se pregunta por qué los controladores de eventos como

$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 

trabajo?

Bueno, no pase content como controlador de eventos, pero la función que se encuentra en content.toggleTweetTextarea. Y esta referencia seguirá existiendo después de que content ya no exista. No hay nada especial al respecto. Acabas de asignar un objeto (la función) a otra variable. Mientras exista al menos una referencia a un objeto, el objeto no se recolectará como basura.

Ahora puede preguntar por qué esas funciones todavía tienen acceso, p. tweetTextArea? Esto es de hecho un cierre. Cuando las funciones se crean a través de new CSContent(), el contexto de activación de esta función se agrega a la cadena de alcance de las funciones internas CSContent.toggleTweetTextarea y CSContent.updateTweetCharacterCount. Por lo tanto, incluso si ya no tiene una referencia al content, el alcance de esta función aún está contenido en la cadena de alcance de las otras funciones.

Ya no podrá acceder al objeto contenido en content después de que ready() haya terminado, esto de hecho está fuera del alcance.

5

Esto, mi señor, que se llama un cierre: la variable local content permanecerá en la memoria después de $(document).ready salidas. Esta es también una causa conocida de pérdidas de memoria.

En resumen, vincula esta función a un detector de eventos de un elemento DOM y, a continuación, el recolector de elementos no utilizados de JavaScript sabe que debe mantener intacta la variable local. No puede llamarlo directamente (fuera de la función), a menos que se desencadene el evento. Con algunos, puede hacer esto 'manualmente', si realmente desea llamar a la función después (por ejemplo, usando element.click() para simular un clic).

+0

Pero aparte de eso, ¡son geniales! :) Algunas lecturas adicionales: https: //developer.mozilla.org/es/JavaScript/Guide/Closures –

+0

Entonces, ¿puede acceder a las variables locales declaradas en el constructor CSContent porque es un cierre, y no sale del alcance porque está vinculado a un detector de eventos? ¿O todo el cierre se copia de alguna manera al oyente del evento? – jergason

+0

@Jergason: el primero. –

1

Mi cerebro está apagado hoy, pero ¿no debería usar cierres en esta situación?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
     content.toggleTweetTextarea(); 
    } 
); 
+0

Hoy ....? :) Hola Eric, ¿alguna vez has visto este comentario: http://stackoverflow.com/questions/3274044/best-book-on-ajax/3306936#3306936 –

+0

Hmm, buena idea, cierres. Pero el OP ya está usando uno ...: P –

Cuestiones relacionadas