[javascript] 재산 변경에 대한 중단 점

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.

편집하다:

console.watchFirefox의 비표준으로 인해 Firefox에는 이미 존재합니다 Object.watch. 따라서 Firefox에서는 기본적으로 변경 사항을 감시 할 수 있습니다.

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

그러나 이것은 곧 (2017 년 말) 제거 될 것 입니다.


답변

이를위한 라이브러리가 있습니다 : BreakOn ()

당신이 조각으로 크롬 개발 도구에 추가하는 경우 (소스 -> 미리보기 -> 오른쪽 클릭 -> 새로 만들기 -> 붙여 넣기 ) , 당신은 언제든지 사용할 수 있습니다.


사용하려면 dev-tools를 열고 스 니펫을 실행하십시오. 그런 다음 myObject.myProperty변경 되었을 때 중단 하려면 dev-console에서 다음을 호출하십시오.

breakOn(myObject, 'myProperty');

라이브러리를 프로젝트의 디버그 빌드에 추가 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);

이제 대신 originalObject를 제공 할 위치에 wrappedObject를 사용하고 중단시 호출 스택을 검사하십시오.


답변

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)


답변

Chrome에는 최신 버전 https://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpoints 에이 기능이 내장되어 있습니다. .

따라서 사용자 정의 라이브러리 및 솔루션이 더 이상 필요하지 않습니다. 인스펙터에서 DOM 요소를 마우스 오른쪽 버튼으로 클릭하고 ‘Break on’-> ‘attribute modified’를 선택하십시오.