Búsqueda de sitios web

javascript - Punto de interrupción en el cambio de propiedad


Firebug para Firefox tiene una buena función, llamada "Detener al cambiar propiedad", donde puedo marcar cualquier propiedad de cualquier objeto, y se detendrá la ejecución de JavaScript justo antes del cambio.

Estoy tratando de lograr lo mismo en Google Chrome, y no puedo encontrar la función en el depurador de Chrome. ¿Cómo hago esto en Google Chrome?

Respuesta #1

Si no te importa trastear con el código fuente, podrías redefinir la propiedad con un accesor.

// original object
var obj = {
    someProp: 10
};

// save in another property
obj._someProp = obj.someProp;

// overwrite with accessor
Object.defineProperty(obj, 'someProp', {
    get: function () {
        return obj._someProp;
    },

    set: function (value) {
        debugger; // sets breakpoint
        obj._someProp = value;
    }
});

Respuesta #2

Hay una biblioteca para esto: BreakOn()

Si lo agregas a las herramientas de desarrollo de Chrome como un fragmento (fuentes --> fragmentos --> clic derecho --> nuevo --> pegar esto --> ejecutar), puedes usarlo en cualquier momento.


Para usarlo, abre las herramientas de desarrollo y ejecuta el fragmento. Luego, para detenerse cuando myObject.myProperty cambie, llama a esto desde la consola de desarrollo:

breakOn(myObject, 'myProperty');

También podrías añadir la biblioteca a la compilación de depuración de tu proyecto para que no necesites llamar a breakOn nuevamente cada vez que actualices la página.

Respuesta #3

Edit 2016.03: Object.observe está en desuso y fue eliminado en Chrome 50

Chrome 36 viene con una implementación nativa de Object.observe que se puede aprovechar aquí:

myObj = {a: 1, b: 2};
Object.observe(myObj, function (changes){
    console.log("Changes:");
    console.log(changes);
    debugger;
})
myObj.a = 42;

Si lo quieres solo temporalmente, deberías almacenar el callback en una variable y llamar a Object.unobserve cuando hayas terminado:

myObj = {a: 1, b: 2};
func = function() {debugger;}
Object.observe(myObj, func);
myObj.a = 42;
Object.unobserve(myObj, func);
myObj.a = 84;

Tenga en cuenta que al usar Object.observe, no se le notificará cuando la asignación no cambió nada, por ejemplo, si ha escrito myObj.a=1.

Para ver la pila de llamadas, necesitas habilitar la opción "pila de llamadas asíncronas" en las Herramientas de Desarrollo:


Respuesta original (2012.07):

Un ejemplo de console.watch como lo sugirió @katspaugh:

var console = console || {}; // just in case
console.watch = function(oObj, sProp) {
   var sPrivateProp = "$_"+sProp+"_$"; // to minimize the name clash risk
   oObj[sPrivateProp] = oObj[sProp];

   // overwrite with accessor
   Object.defineProperty(oObj, sProp, {
       get: function () {
           return oObj[sPrivateProp];
       },

       set: function (value) {
           //console.log("setting " + sProp + " to " + value); 
           debugger; // sets breakpoint
           oObj[sPrivateProp] = value;
       }
   });
}

Invocación:

console.watch(obj, "someProp");

Compatibilidad:

  • ¡En Chrome 20, puedes pegarlo directamente en las Herramientas de Desarrollo en tiempo de ejecución!
  • Para mayor completitud: en Firebug 1.10 (Firefox 14), tienes que inyectarlo en tu sitio web (por ejemplo, vía Fiddler si no puedes editar el código fuente manualmente); lamentablemente, las funciones definidas desde Firebug no parecen detenerse en debugger (¿o es una cuestión de configuración? corríjanme entonces), pero console.log funciona.
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69

Editar: Object.watch fue eliminado en Firefox 57.

Artículos relacionados