Firefox用のFirebugには、「プロパティの変更時に中断」と呼ばれる優れた機能があります。この機能では、任意のオブジェクトの任意のプロパティにマークを付けることができ、変更の直前にJavaScriptの実行を停止します。
Google Chromeで同じことを実現しようとしていますが、Chromeデバッガーで機能が見つかりません。Google Chromeでこれを行うにはどうすればよいですか?
Firefox用のFirebugには、「プロパティの変更時に中断」と呼ばれる優れた機能があります。この機能では、任意のオブジェクトの任意のプロパティにマークを付けることができ、変更の直前にJavaScriptの実行を停止します。
Google Chromeで同じことを実現しようとしていますが、Chromeデバッガーで機能が見つかりません。Google 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.observe
Chrome 50では非推奨になり、削除されました
Object.observe
Chrome 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
。
コールスタックを表示するには、開発ツールで「非同期コールスタック」オプションを有効にする必要があります。
元の回答(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");
互換性:
debugger
(または構成の問題ですか?それでは修正してください)が、console.log
機能します。>>> var obj = { foo: 42 }
>>> obj.watch('foo', function() { console.log('changed') })
>>> obj.foo = 69
changed
69
編集:Object.watch
Firefox57で削除されました。
このためのライブラリがあります: BreakOn()
Chrome開発ツールにスニペットとして追加すると([ソース]->[スニペット]->[右クリック]->[新規]->[これを貼り付け]-> [実行])、いつでも使用できます。
これを使用するには、dev-toolsを開いてスニペットを実行します。次に、myObject.myProperty
が変更されたときに中断するには、dev-consoleからこれを呼び出します。
breakOn(myObject, 'myProperty');
breakOn
プロジェクトのdebug-buildにライブラリを追加して、ページを更新するたびに再度呼び出す必要がないようにすることもできます。
これは、プロキシによってラップされたオブジェクトへの読み取りと書き込みをインターセプトすることを目的とした新しいプロキシオブジェクトを使用して実行することもできます。監視するオブジェクトをプロキシにラップし、元のオブジェクトの代わりに新しいラップされたオブジェクトを使用するだけです。
例:
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)
Alexandos Katechisによる優れたソリューションに基づいて、プロパティの元の値を乱さないバージョンのスニペットを次に示します。使用するときに考えていることと一致するように名前を変更しました。
使用法:
breakOnChange(anyObject, 'propertyName')
コンソールで呼び出すこれは、サードパーティのスクリプトによって踏みにじられている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)
Chromeには、最新バージョンhttps://developers.google.com/web/updates/2015/05/view-and-change-your-dom-breakpointsにこの機能が組み込まれています。
したがって、カスタムライブラリやソリューションはもう必要ありません。インスペクターでDOM要素を右クリックし、[中断]->[属性の変更]を選択するだけです。