Programing

재산 변경에 대한 중단 점

crosscheck 2020. 6. 23. 07:46
반응형

재산 변경에 대한 중단 점


Firefox 용 Firebug에는 "속성 변경시 중단"이라는 멋진 기능이 있는데, 여기서 객체의 모든 속성을 표시 할 수 있으며 변경 직전에 JavaScript 실행이 중지됩니다.

Chrome에서 동일한 결과를 얻으려고하는데 Chrome 디버거에서 기능을 찾을 수 없습니다. Chrome에서 어떻게해야합니까?


소스를 망칠 염려가 없다면 접근자를 사용하여 속성을 재정의 할 수 있습니다.

// 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.observeChrome 50에서 사용되지 않으며 제거되었습니다.

2014.05 수정 : Object.observeChrome 36에 추가되었습니다

Chrome 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) :

console.watch@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;
       }
   });
}

기도:

console.watch(obj, "someProp");

적합성:

  • Chrome 20에서는 런타임에 개발자 도구에 직접 붙여 넣을 수 있습니다!
  • 완벽 함 : Firebug 1.10 (Firefox 14)에서는 웹 사이트에 소스를 삽입해야합니다 (예 : 소스를 수동으로 편집 할 수없는 경우 Fiddler를 통해). 슬프게도 Firebug에서 정의 된 기능은 깨지지 않는 것 같습니다 debugger(또는 구성의 문제입니까? 그런 다음 나를 수정하십시오) console.log.

편집하다:

Note that in Firefox, console.watch already exists, due to Firefox's non-standard Object.watch. Hence in Firefox, you can watch for changes natively:

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

However, this will be soon (late 2017) removed.


There is a library for this: BreakOn()

If you add it to Chrome dev tools as a snippet (sources --> snippets --> right-click --> new --> paste this), you can use it anytime.


To use it, open the dev-tools and run the snippet. Then to break when myObject.myProperty is changed, call this from the dev-console:

breakOn(myObject, 'myProperty');

You could also add the library to your project's debug-build so you don't need to call breakOn again every time you refresh the page.


This can also be done by using the new Proxy object whose purpose is exactly that: intercepting the reads and writes to the object that is wrapped by the Proxy. You simply wrap the object you would like to observe into a Proxy and use the new wrapped object instead of your original one.

Example:

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

Now use wrappedObject where you would supply originalObject instead and examine the call stack on break.


Chrome has this feature built-in in latest versions https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints.

So no more needs for custom libraries and solutions, just right click on DOM element in the inspector and choose 'Break on' -> 'attribute modifications' and that's it.


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

이 솔루션의 자체 버전을 작성하기로 결정하고 Chrome의 DevTools의 스 니펫에 저장 한 다음 노드와 브라우저를 모두 지원해야하는 IIFE로 래핑했습니다. 또한 이름 충돌의 가능성이없고 키를 열거하는 코드가 생성 된 새로운 "개인 키"를 "보지"않을 수 있도록 개체의 속성 대신 범위 변수를 사용하도록 관찰자를 변경했습니다.

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

참고 URL : https://stackoverflow.com/questions/11618278/breakpoint-on-property-change

반응형