¿Es posible acceder al cierre de una función?

Resuelto Denys Séguret asked hace 12 años • 4 respuestas

Una función en javascript forma un cierre manteniendo un enlace (oculto) a su alcance adjunto.

¿Es posible acceder a él mediante programación cuando tenemos la función (como valor de variable)?

El objetivo real es teórico, pero una demostración podría ser enumerar las propiedades del cierre.

var x = (function(){
   var y = 5;
   return function() {
       alert(y);
   };
})();

//access y here with x somehow
Denys Séguret avatar Jun 25 '12 22:06 Denys Séguret
Aceptado

Si está en un entorno front-end y puede ejecutar su propio Javascript en una etiqueta de script anterior , una opción es adjuntar un MutationObserver, espere a que se inserte en el documento la etiqueta de script que desea espiar. y justo cuando se inserte, cambie su código para que quede expuesta la funcionalidad que desea examinar o cambiar. He aquí un ejemplo:

<script>
new MutationObserver((mutations, observer) => {
  // Find whether the script tag you want to tamper with exists
  // If you can't predictably identify its location,
  // you may have to iterate through the mutations' addedNodes
  const tamperTarget = document.querySelector('script + script');
  if (!tamperTarget) {
    return;
  }
  observer.disconnect();
  console.log('Target script getting tampered with');
  tamperTarget.textContent = tamperTarget.textContent.replace(
    'return function',
    'window.y = y; return function'
  );
  setTimeout(() => {
    console.log("Hacked into tamper target's script and found a y of", y);
    console.log('Could also have replaced the local y with another value');
  });
})
  .observe(document.body, { childList: true });

</script>

<script>
console.log('Tamper target script running');
var x = (function(){
   var y = 5;
   return function() {
       alert(y);
   };
})();
</script>
Expandir fragmento

Puede que esto no fuera lo que tenías en mente, pero este tipo de método es una de las pocas formas de hackear un cierre, lo cual es una técnica útil cuando la página ejecuta código que no puedes cambiar.

Si el otro script tiene un srccódigo en lugar de un código en línea, será un poco más difícil. Cuando <script>MutationObserver vea la etiqueta, modifíquela o reemplácela con una nueva etiqueta de script cuyo textContentcontenido sea el script original más sus modificaciones . Para obtener el contenido original, examine el código incorporado <script>y codifique su reemplazo, o busque el texto de la etiqueta del script (posiblemente rebotando la solicitud en otro servidor para evitar problemas de CORS) antes de poder realizar los reemplazos necesarios y inserte el código parcheado. (O, si tiene un servidor, puede hacer que el servidor realice los reemplazos de texto; luego, todo lo que necesita hacer es cambiar la srcetiqueta de secuencia de comandos insertada para que apunte a su servidor en lugar de a la ubicación predeterminada).

CertainPerformance avatar Dec 20 '2019 11:12 CertainPerformance

Ese es (uno de) los propósitos de un cierre: mantener la información privada. Dado que la función ya se ha ejecutado, sus variables de alcance ya no están disponibles desde el exterior (y nunca lo han estado); solo las funciones ejecutadas en su alcance (todavía) tienen acceso.

Sin embargo, puede dar acceso a través de captadores/definidores.

Quizás quieras echar un vistazo a la charla de Stuart Langridge sobre cierres. También son muy recomendables las explicaciones de Douglas Crockford. Puedes hacer muchas cosas elegantes con cierres;)

Editar: tiene varias opciones para examinar el cierre: observar el objeto en la consola del desarrollador web o (como lo hago a menudo) devolver una función de depuración que descarga todas las variables privadas en la consola.

Christoph avatar Jun 25 '2012 16:06 Christoph