167

Firefox用のFirebugには、「プロパティの変更時に中断」と呼ばれる優れた機能があります。この機能では、任意のオブジェクトの任意のプロパティにマークを付けることができ、変更の直前にJavaScriptの実行を停止します。

Google Chromeで同じことを実現しようとしていますが、Chromeデバッガーで機能が見つかりません。Google Chromeでこれを行うにはどうすればよいですか?

4

8 に答える 8

126

ソースをいじり回してもかまわない場合は、アクセサを使用してプロパティを再定義できます。

// 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;
    }
});
于 2012-07-23T18:35:00.627 に答える
115

2016.03の編集:Object.observeChrome 50では非推奨になり、削除されました

** 2014.05の編集:`Object.observe`がChrome36に追加されました**

Object.observeChrome 36には、ここで活用できるネイティブ実装が付属しています。

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

コールスタックを表示するには、開発ツールで「非同期コールスタック」オプションを有効にする必要があります。

chrome非同期呼び出しスタック


元の回答(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)では、Webサイトに挿入する必要があります(ソースを手動で編集できない場合は、Fiddlerを使用するなど)。悲しいことに、Firebugから定義された関数は壊れていないようですdebugger(または構成の問題ですか?それでは修正してください)が、console.log機能します。
Firefoxには、Firefoxの非標準[`Object.watch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)のため、`console.watch`がすでに存在することに注意してください。 / Object / watch)。したがって、Firefoxでは、変更をネイティブに監視できます。
>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69

編集:Object.watchFirefox57で削除されました。

于 2012-07-25T21:10:18.307 に答える
97

このためのライブラリがあります: BreakOn()

Chrome開発ツールにスニペットとして追加すると([ソース]->[スニペット]->[右クリック]->[新規]->[これを貼り付け]-> [実行])、いつでも使用できます。

ここに画像の説明を入力してください


これを使用するには、dev-toolsを開いてスニペットを実行します。次に、myObject.myPropertyが変更されたときに中断するには、dev-consoleからこれを呼び出します。

breakOn(myObject, 'myProperty');

breakOnプロジェクトのdebug-buildにライブラリを追加して、ページを更新するたびに再度呼び出す必要がないようにすることもできます。

于 2016-07-28T20:25:58.477 に答える
6

これは、プロキシによってラップされたオブジェクトへの読み取りと書き込みをインターセプトすることを目的とした新しいプロキシオブジェクトを使用して実行することもできます。監視するオブジェクトをプロキシにラップし、元のオブジェクトの代わりに新しいラップされたオブジェクトを使用するだけです。

例:

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を使用し、ブレーク時に呼び出しスタックを調べます。

于 2017-11-25T14:21:28.850 に答える
5
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;
    }
  });
}
于 2018-01-18T06:54:46.817 に答える
3

このソリューションの独自のバージョンを作成し、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)
于 2019-05-08T18:15:43.373 に答える
1

Alexandos Katechisによる優れたソリューションに基づいて、プロパティの元の値を乱さないバージョンのスニペットを次に示します。使用するときに考えていることと一致するように名前を変更しました。

使用法:

  1. [ソース]->[スニペット]からスニペットを追加します
  2. 必要に応じて、Command-Oを押して、breakOnChangeスニペットの実行を選択します
  3. breakOnChange(anyObject, 'propertyName')コンソールで呼び出す
  4. 変化を引き起こす行動を取る
  5. デバッガーで停止します

これは、サードパーティのスクリプトによって踏みにじられているjQueryなどのグローバルライブラリのようなものを見つけるのに非常に役立ちます。

(function (global) {
  global.breakOnChange = (obj, prop) => {
    let value = obj[prop]

    Object.defineProperty(obj, prop, {
      get: function () {
        return value
      },

      set: function (newValue) {
        debugger
        value = newValue
      },
    })
  }
})(typeof process !== 'undefined' ? process : window)
于 2021-03-01T17:19:47.490 に答える
-3

Chromeには、最新バージョンhttps://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpointsにこの機能が組み込まれています。

したがって、カスタムライブラリやソリューションはもう必要ありません。インスペクターでDOM要素を右クリックし、[中断]->[属性の変更]を選択するだけです。

于 2018-06-02T09:20:29.177 に答える