2012-07-23 3 views
102

Firebug dla firefox ma fajną funkcję, o nazwie "Break on property change", w której mogę oznaczyć dowolną właściwość dowolnego obiektu, a to zatrzyma wykonywanie javascript tuż przed zmianą.Jak "włamać się do zmiany własności" w chrome?

Próbuję osiągnąć to samo w Google Chrome i nie mogę znaleźć funkcji w chrome debugerze. Jak to zrobić w Google Chrome?

+1

Jeśli chcesz to zrobić z elementów HTML zobaczyć http://stackoverflow.com/a/32686203/308851 – chx

Odpowiedz

65

Jeśli nie masz nic przeciwko pogawędkom ze źródłem, możesz zmienić definicję nieruchomości za pomocą akcesora.

// 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; 
    } 
}); 
+2

jest tam korek, w którym byłoby to dla mnie zrobić? –

+3

@ArsenZahray, dunno. Możesz jednak zrobić z niego przydatną funkcję i użyć jej w stylu 'console.watch (obj, 'someProp')'. – katspaugh

+2

To nie działa dla wbudowanych właściwości, takich jak 'window.location' ze względów bezpieczeństwa. – qJake

94

Edycja 2016,03: Object.observe jest przestarzała i usunięto Chrome 50

Edycja 2014,05: Object.observe dodano Chrome 36

Chrom 36 statków z natywnym Object.observe wykonania, który może można zastosować tutaj:

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

Jeśli chcesz go tylko tymczasowo, należy przechowywać zwrotnego w zmiennej i wywołać Object.unobserve kiedy zrobić:

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

Należy pamiętać, że podczas korzystania Object.observe, nie będziesz otrzymywać powiadomienia o przypisanie nic nie zmieni np jeśli napisałeś myObj.a = 1.

Aby zobaczyć stos wywołań, musisz włączyć opcję "asynchroniczne wywołanie stosu" w Dev Narzędzia:

chrome async call stack


odpowiedź Original (2012,07):

Szkic console.watch sugerowany przez @katspaugh:

console = console || {}; // just in case 
console.watch = function(oObj, sProp) { 
    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; 
     } 
    }); 
} 

Inwokacja:

console.watch(obj, "someProp"); 

Kompatybilność:

  • W Chrome 20, można wkleić go bezpośrednio w Dev Tools przy starcie!
  • Dla kompletności: w Firebug 1.10 (Firefox 14), musisz wstrzyknąć go na swoją stronę (np. Za pomocą Fiddlera, jeśli nie możesz ręcznie edytować źródła); Niestety, funkcje zdefiniowane przez Firebug nie wydają się łamać na debugger (czy jest to kwestia konfiguracji? proszę poprawić mnie wtedy), ale działa console.log.

Edit:

Należy zauważyć, że w Firefox, console.watch już istnieje, ze względu na Firefoksa niestandardowym Object.watch.Stąd w Firefoksie można obserwować zmiany natywnie:

>>> var obj = { foo: 42 } 
>>> obj.watch('foo', function() { console.log('changed') }) 
>>> obj.foo = 69 
changed 
69 

Jednak this will be soon (late 2017) removed.

+0

Dzięki, bardzo miło! – katspaugh

+1

Przy okazji wydaje się, że nie można trafić debuggera w niestandardowym kodzie jest regresja między Firebug 1.8 i 1.9: [problem 5757] (http://code.google.com/p/fbug/issues/detail?id=5757) -> duplikat [wydanie 5221] (http://code.google.com/p/fbug/issues/detail?id=5221) –

+0

Jest to bardzo pomocne! – Wint

46

Jest to biblioteka dla: BreakOn()

Jeśli dodać go do narzędzi dev Chrome jako urywek (źródła -> fragmenty -> kliknij prawym przyciskiem myszy -> Nowy -> wklej this), możesz go użyć w dowolnym momencie.


Aby z niego skorzystać, otwórz dev-tools i uruchom fragment kodu. Następnie przełamać kiedy myObject.myProperty ulega zmianie, zadzwoń do tego z dev-konsoli:

breakOn(myObject, 'myProperty'); 

Można też dodać bibliotekę do debugowania-Build Your projektu, dzięki czemu nie trzeba zadzwonić breakOn ponownie za każdym razem odświeżyć strona.

+2

Genialny! Działa dla mnie w przeglądarce Google Chrome 52.0.2743.116. –

+2

Fantastyczne! Byłem zaskoczony, że działało nawet z 'breakOn (myElement.style, 'transform')' dla mnie, Chrome 56. –

+1

Działa na Chrome 60.0.3112.90 z breakOn (myInputElement, 'value'). –

0

Można to również zrobić za pomocą nowego obiektu Proxy, którego celem jest dokładnie: przechwytywanie odczytów i zapisów do obiektu zapakowanego przez serwer proxy. Po prostu oblewaj obiekt, który chcesz obserwować, w Proxy i używaj nowego owiniętego obiektu zamiast oryginalnego.

Przykład:

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); 

Teraz użyj wrappedObject gdzie byś zamiast dostarczać originalObject i bada stos wywołań na przerwie.

0
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; 
    } 
    }); 
} 
Powiązane problemy