Точка останова при изменении свойства
Firebug для Firefox имеет приятную функцию, называемую "Break on property change", где я могу отметить любое свойство любого объекта, и он остановит выполнение JavaScript прямо перед изменением.
Я пытаюсь добиться того же в Google Chrome, и я не могу найти функцию в Chrome debugger. Как это сделать в Google Chrome?
6 ответов:
Если вы не возражаете возиться с источником, вы можете переопределить свойство с помощью метода доступа.
// 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; } });
изменить 2016.03:
Object.observe
является устаревшим и удаляется в Chrome 50
изменить 2014.05:Object.observe
был добавлен в Chrome 36Chrome 36 поставляется с родной
Object.observe
реализация, которая может быть использована здесь:myObj = {a: 1, b: 2}; Object.observe(myObj, function (changes){ console.log("Changes:"); console.log(changes); debugger; }) myObj.a = 42;
если вы хотите его только временно, вы должны сохранить обратный вызов в переменной и вызвать
Object.unobserve
когда сделано:myObj = {a: 1, b: 2}; func = function() {debugger;} Object.observe(myObj, func); myObj.a = 42; Object.unobserve(myObj, func); myObj.a = 84;
обратите внимание, что при использовании
Object.observe
, вы не будете уведомление, когда назначение ничего не изменило, например, если вы написалиmyObj.a = 1
.чтобы увидеть стек вызовов, вам нужно включить опцию "асинхронный стек вызовов" в инструментах разработки:
оригинальный ответ (2012.07):
A
console.watch
эскиз как предложил @кэтспо: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; } }); }
ссылка:
console.watch(obj, "someProp");
совместимость:
- In Chrome 20, вы можете вставить его непосредственно в Dev Tools во время выполнения!
- для полноты: в Firebug 1.10 (Firefox 14) вы должны ввести его на свой сайт (например, через Fiddler, если вы не можете редактировать источник вручную); к сожалению, функции, определенные из Firebug, похоже, не ломаются
debugger
(или это вопрос конфигурации? пожалуйста, поправьте меня тогда), ноconsole.log
строительство.Edit:
обратите внимание, что в Firefox
console.watch
уже существует, из-за нестандартного FirefoxObject.watch
. Следовательно, в Firefox вы можете следить за изменениями изначально:>>> var obj = { foo: 42 } >>> obj.watch('foo', function() { console.log('changed') }) >>> obj.foo = 69 changed 69
однако, это будет в ближайшее время (в конце 2017 года) удалены.
для этого есть библиотека:BreakOn()
Если вы добавите его в Chrome dev tools в виде фрагмента (источники -- > фрагменты -- > щелкните правой кнопкой мыши -- > создать -- > вставить этой), вы можете использовать его в любое время.
чтобы использовать его, откройте dev-tools и запустите фрагмент кода. Тогда ломать когда
myObject.myProperty
изменяется, вызовите это из dev-консоли:breakOn(myObject, 'myProperty');
вы также можете добавить библиотеку в debug-build вашего проекта, чтобы вы не нужно звонить
breakOn
снова при каждом обновлении страницы.
Это также можно сделать с помощью Прокси объект, целью которого является именно это: перехват чтения и записи в объект, который обернут Прокси. Вы просто обертываете объект, который хотите наблюдать, в прокси-сервер и используете новый обернутый объект вместо исходного.
пример:
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);
теперь используйте wrappedObject, где вы бы поставить originalObject вместо этого и изучить стек вызовов на перерыв.
Chrome имеет эту функцию встроенную в последних версиях https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints.
Так что больше нет необходимости в пользовательских библиотеках и решениях, просто щелкните правой кнопкой мыши на элементе DOM в инспекторе и выберите "Break on" - > "attribute modifications" и все.
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; } }); }