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), peroconsole.logfunciona.
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
Editar: Object.watch fue eliminado en Firefox 57.

