Firebug pour Firefox a une fonctionnalité Nice, appelée "Break on property change", dans laquelle je peux marquer n'importe quelle propriété d'un objet, et qui arrête l'exécution de JavaScript juste avant la modification.
J'essaie d'obtenir le même résultat dans Google Chrome et je ne trouve pas la fonction dans le débogueur Chrome). Comment puis-je procéder dans Google Chrome?
Si cela ne vous dérange pas de jouer avec la source, vous pouvez redéfinir la propriété avec un accesseur.
// 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;
}
});
Éditer 2016.03: Object.observe
est obsolète et supprimé dans Chrome 50
Édition 2014.05: Object.observe
a été ajouté dans Chrome 36
Chrome 36 est livré avec Object.observe
mise en œuvre qui peut être exploitée ici:
myObj = {a: 1, b: 2}; Object.observe(myObj, function (changes){ console.log("Changes:"); console.log(changes); debugger; }) myObj.a = 42;
Si vous ne le souhaitez que temporairement, vous devez stocker le rappel dans une variable et appeler Object.unobserve
lorsque vous avez terminé:
myObj = {a: 1, b: 2}; func = function() {debugger;} Object.observe(myObj, func); myObj.a = 42; Object.unobserve(myObj, func); myObj.a = 84;
Notez que lorsque vous utilisez Object.observe
, vous ne serez pas averti lorsque l’affectation n’a rien changé, par exemple. si vous avez écrit myObj.a = 1
.
Pour voir la pile d'appels, vous devez activer l'option "Pile d'appels async" dans les outils de développement:
Réponse originale (2012.07):
UNE console.watch
_ esquisse suggérée par @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;
}
});
}
Invocation:
console.watch(obj, "someProp");
Compatibilité:
debugger
(ou est-ce une question de configuration? corrigez-moi alors), mais console.log
travaux.Modifier:
Notez que dans Firefox, console.watch
existe déjà, en raison de la non-standard de Firefox Object.watch
. Par conséquent, dans Firefox, vous pouvez surveiller les modifications de manière native:
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
Cependant, cela sera bientôt (fin 2017) supprimé .
Il existe une bibliothèque pour cela: BreakOn ()
Si vous l'ajoutez à Chrome dev tools sous forme d'extrait de code (sources -> extraits de code -> clic-droit -> nouveau -> coller - this ) , vous pouvez l'utiliser à tout moment.
Pour l'utiliser, ouvrez les dev-tools et exécutez l'extrait de code. Puis casser quand myObject.myProperty
est modifié, appelez-le depuis la console de développement:
breakOn(myObject, 'myProperty');
Vous pouvez également ajouter la bibliothèque à la version de débogage de votre projet afin de ne pas avoir à appeler breakOn
à chaque fois que vous actualisez la page.
Cela peut également être fait en utilisant le nouvel objet Proxy dont le but est exactement le suivant: intercepter les lectures et les écritures sur l'objet encapsulé par le proxy. Vous intégrez simplement l'objet que vous souhaitez observer dans un proxy et utilisez le nouvel objet enveloppé au lieu de celui d'origine.
Exemple:
const originalObject = {property: 'XXX', propertyToWatch: 'YYY'};
const watchedProp = 'propertyToWatch';
const handler = {
set(target, key, value) {
if (key === watchedProp) {
debugger;
}
target[key] = value;
}
};
const wrappedObject = new Proxy(originalObject, handler);
Maintenant, utilisez wrappedObject où vous fourniriez à la place originalObject et examinerez la pile d'appels à la rupture.
Cette fonctionnalité est intégrée à Google Chrome dans les dernières versions. https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints .
Vous n'avez donc plus besoin de bibliothèques et de solutions personnalisées, cliquez simplement avec le bouton droit de la souris sur l'élément DOM dans l'inspecteur et choisissez "Interrompre" -> "attribuer les modifications", et c'est tout.
function debugProperty(obj, propertyName) {
// save in another property
obj['_' + propertyName] = obj[propertyName];
// overwrite with accessor
Object.defineProperty(obj, propertyName, {
get: function() {
return obj['_' + propertyName];
},
set: function(value) {
debugger; // sets breakpoint
obj['_' + propertyName] = value;
}
});
}
Décidé d'écrire ma propre version de cette solution, de l'enregistrer dans un extrait de l'outil de développement de Chrome et de l'envelopper dans un IIFE prenant en charge à la fois Node et les navigateurs. Changé également l'observateur pour utiliser une portée variable plutôt qu'une propriété sur l'objet, de sorte qu'il n'y a aucune possibilité de conflit de nom, et tout code qui énumère des clés ne "verra" pas la nouvelle "clé privée" créée:
(function (global) {
global.observeObject = (obj, prop) => {
let value
Object.defineProperty(obj, prop, {
get: function () {
return value
},
set: function (newValue) {
debugger
value = newValue
},
})
}
})(typeof process !== 'undefined' ? process : window)