最適化をオフにできるので、クロージャーからのスコープ内変数は「最適化されません」。


11

最近のブラウザーで行われたコード最適化の副産物として、デバッグ中に、「実際に」スコープ内にあるすべての変数を「見る」ことはできません。これはよく知られており、SOに関する前の質問で対処されています。この機能は、確かに本番環境では便利ですが、開発中に私を悩ませますが、遅くなります(それは明らかです)。

今私の質問は、この動作をオフにする方法はありますか?構成ファイルを編集できますか、それともブラウザプラグインがありますか、それともブラウザ実行可能ファイルの「開発者向けの特別なビルドバージョン」がありますか?新しいコードを書いているとき、すぐにコードをコンソールに入力するのが好きなので、これは本当に私を悩ませています。

visualSummaryIffalseConsoleLog

更新/編集

これは、部分的な解決策です。Paul1365972の功績です。

次のような特別なオプションを使用して、コマンドラインからChromeブラウザを起動する必要があります。

  1. Chromeを完全に閉じます
  2. コンソールからChromeを実行します"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" 。これは、他のWindows OSと同様です。
  3. 開発者コンソールを開いて実行し"%GetHeapUsage()"ます。オプションを使用してChromeを適切に起動した場合、番号がコンソールに記録されます。それ以外の場合は、構文エラーが発生します。

このコマンドラインフラグを使用すると%、で始まるコマンドを使用して「V8エンジンと通信」できます。これは、プレーンJavaScriptの構文エラーです。この種の使用可能なV8コマンドのリストは、Paulの回答記載されています

あり%NeverOptimizeFunction()、私はちょうど呼び出すことと、それを使って行うことがあるだろうことのように見えたものですそのリスト、上。残念ながら、次のスクリーンショットに示すように、その関数は私が望んでいたことをしません。

loremはまだ定義されていません

(((Paulの回答からもう1つのリンク(v8ネイティブノードモジュール)は、このコンテキストではここでは重要ではありません。コードがクラッシュしないように、「%」関数呼び出しを1行で囲むだけです。 v8ではないブラウザー)))

(((これが機能したとき(この最適化がまだ発明/実装されていないとき)を覚えています。10年前、15年前、そのようなものです。Chromeの最新バージョンは何ですか(もしそして、あなたができる最後のFirefoxバージョンは何でしたか(もっと確かにここにあります)?それはあなたに賞金をもたらすことはありませんが、もしあなたがたまたま知っていてそれを回答として投稿した場合、あなたは賛成票を得るでしょう。 。)))

ソリューション

PETR SRNICEKに感謝

ハックフィックス

新しい質問

ペトルのソリューションは多くのことを助けますが、完璧ではありません。この質問は長くなりすぎているので、Petrのソリューションをどのように改善できるかについて新しい質問を投稿しました。(もちろん、ここでこの質問を編集することもできますが、私が何を意味するのかを知っていれば、それは「歴史的でない」と感じるでしょう。)


意図しない結果、章tenthosandone。この最適化は、私のコーディングスタイルに悪影響を及ぼします。(.map、.forEach、.reduceの代わりに)古い形式のforループを使用していることに気づきましたが、この問題に遭遇しないようにしています。
mathheadinclouds '18年

v8-nativesライブラリは、ちょうどべきであるシンプルなライブラリのコードで重要な%コールラップnoops..特別--allow-原住民-構文フラグで開始されませんでしたブラウザやノード内を
ナタナエル

私はいくつかのテストを実行しましたが、 'bodyOnLoad'関数はとにかく最適化されていません。そのため、内部コマンドを使用して強制的に最適化を解除しても、何も起こりません。
ナタナエル

@Nathanael:重要な呼び出しは、%NeverOptimizeFunction(foo)私がbodyOnloadでも呼び出しただけです。問題は、foo私が望んでいた方法で最適化されていないことです。変数loremは見えません。関数fooに入るコードを書きたいとしましょう。テキストエディターに入力する代わりに、(デバッガーがfooに座っている間に)開発コンソールに入力し、期待どおりに機能するかどうかを確認してから、コンソールからテキストエディターにコピーして貼り付けます。それが私が働くのが好きな方法です。そしてできません。最適化のため。それを得る?
mathheadinclouds

1
Paul1365972が回答を投稿する前に、さまざまな--js-flags(いくつかのTurboFan関連のコマンドを含む)およびいくつかのV8ネイティブコマンドを実験するのに費やしましたが、希望の動作を達成できませんでした。このアプローチは行き止まりかもしれないと思います。[v8]この質問にタグを追加することは価値があるかもしれません。V8の内部の仕組みを深く理解している人なら、これが正しい方法かどうかを明確にできるかもしれません。
PetrSrníček19年

回答:


2

デバッガーステートメントを次のようなevalでラップすることにより、すべての変数にアクセスできますeval("debugger;");。このハッキーなソリューションは、コールスタックに別の匿名関数を追加しますが、DevToolsで手動で設定されたブレークポイントには明らかに役に立ちません。

これは非常に良い解決策ではないようですが、これが意図された動作をこれまでに達成した唯一のものなので、私はそれを回答として投稿しています。


これが機能するのは、ちょっと驚きです。私はeval( "lorem")と入力してみたところ、同じ "lorem is not defined"エラーが発生しました。コンソールでeval( "lorem")を入力すると(関数fooのデバッガーステートメントで)、eval( "debugger")が実行していることとは異なる動作をするはずです-期待して、 "ipsum"を出力してくださいコンソールに。しかし、それらは非常に異なります。奇妙な。
mathheadinclouds

これは興味深い回避策です。デバッガのステートメントから抜け出せない(手動でソースファイルに切り替える必要がある)ため、少しハックです。そうしないと、スタック全体が失われ、evalを呼び出した関数に戻ります。削減されたスタックには他のコンテキストがありません。
ナタナエル

したがって、このトリックを変更することができます:eval( "debugger")の代わりにeval( "")だけを入れます-しかし、それらの多くは、「拡張ブレークポイント」が必要だと思われるあらゆる場所にコード全体に分散されています。次に、それらのeval( '')ステートメントの1つがあるブレークポイントを(開発ツールを使用して)設定できます。そこで停止すると、「ステップイン」します。これらのステートメントを各関数の先頭に置く小さなトランスパイラー(私がやっている小さなことを意味する大きな言葉)を書くことを検討しています。stackoverflow.com/questions/59159996/...
mathheadinclouds

私はeval( "debugger")をeval();に置き換えてみました。デバッガー、Firefoxまたはchromeの使用状況に応じて、異なる結果が得られました。i.stack.imgur.com/wy5WT.png
mathheadinclouds

3

Google ChromeはV8 JS-Engineを使用します。--allow-natives-syntaxフラグを使用して、ネイティブコールを有効にできます。これにより、探しているもののような多くの便利なデバッグ関数(ここに完全なリスト)が公開されます:%NeverOptimizeFunction() 。このフラグがないと、これらの呼び出しは不正な構文になるため、展開するときは注意してください(またはv8ネイティブライブラリを使用してください)。

この機能を有効にするには、--js-flags = "-allow-natives-syntax"でchromeを開くだけです(これは、信頼できないWebサイトのデバッグにのみ使用してください。これにより、信頼できないjsコードが、本当に望まないものにアクセスする可能性があります。にアクセスできます)。


ありがとうございました。私の更新された質問を読んでください。ここに解決策を持っている可能性はかなり高いようですが、それを実現するにはさらに説明が必要です。これが機能する場合、あなたは確かに賞金に値します。
mathheadinclouds

tl; dr代わりに--js-flags = "-allow-natives-syntax"を使用してください。この機能を有効にするには、V8 JS-Engineを--allow-natives-syntaxフラグで開始する必要がありますが、直接開始することはできません。これはChromeジョブです。したがって、フラグを付けてエンジンを始動するようにクロムに指示する必要があります。どうすればよいですか?上記のエンジンフラグを--js-flags = <your flag here>を介してChromeに渡すだけです。
Paul1365972

いいえ。安全のためにもう一度試してみました。私は両方試してみました--allow-natives-syntaxし、--js-flags="--allow-natives-syntax"「オペレーティングシステムコンソールの『クローム』の後の事のI型」として複数回。私自身もこれを試していないのであれば、私も誤植が最もありそうな説明だと思います。別のスクリーンショットを作成しました。i.stack.imgur.com/7cpPP.png誤植を参照してください?正直に答えてください。「記事を読んで理解した」だけです(明確にするために、これ以上主張しない場合は何も問題ありません)。それとも、実際にすべてをマシンで試しましたか?thx
mathheadinclouds

ただの推測:それは私がそのオプションでクロム実行可能ファイル起動しないのではなく、そのオプションでクロムC ++(または何でも)ソースコンパイルすることですか?
mathheadinclouds

1
それは奇妙なことですが、テストしただけで問題なく動作しました。コンパイルは必要ありません。私は自分がしたことを正確に書くだけなので、誤解はありません。1. Chromeを完全に閉じます。2。 "C:/ Program Files(x86)/Google/Chrome/Application/chrome.exe" --js-flags = "-allow-natives-syntax"を使用してコンソールからChromeを実行します。3。開く開発者コンソールで「%GetHeapUsage()」を実行して、すべてが機能しているかどうかをテストします
Paul1365972 '25

0

私はこの質問が実際の答えを持っていることを本当に望みます。以下は本当の答えではなく、その場しのぎです。if (false) { console.log(variables, from, closures); }静的分析を使用してフォームの愚かなヘルパーコード(問題のスクリーンショットを参照)を作成できるヘルパーツールを作成しました-コードに貼り付けると、愚かなステートメントが作成され、コピーできるので、必要ありません。入力します。このすべてのコピーと貼り付けにも時間がかかるので、それが大きな助けになるかどうかはわかりませんが、それは私が得たものです。

スクリーンショット

バイオリン

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.