dapatkah saya mematikan pengoptimalan, sehingga variabel dalam lingkup dari penutupan tidak "dioptimalkan"


11

Sebagai produk sampingan dari optimasi kode yang dilakukan oleh browser modern, saat debugging, Anda tidak dapat "melihat" semua variabel yang "faktual" berada dalam ruang lingkup. Ini dikenal dan telah dibahas dalam pertanyaan sebelumnya di SO . Fitur ini, walaupun sangat berguna dalam produksi sangat mengganggu saya selama pengembangan, ini memperlambat saya (yang seharusnya sudah jelas.)

Sekarang pertanyaan saya adalah, adakah cara untuk mematikan perilaku ini? Dapatkah saya mengedit beberapa file konfigurasi, atau apakah ada plugin browser, atau mungkin ada "versi build khusus untuk pengembang" dari browser yang dapat dieksekusi? Saya suka mengetik kode saya ke konsol segera ketika saya sedang menulis kode baru, jadi ini benar-benar menggangguku.

visualSummaryIffalseConsoleLog

UPDATE / EDIT

Berikut adalah solusi parsial, kredit kepada Paul1365972.

Anda harus memulai browser chrome dari baris perintah, dengan opsi khusus, seperti:

  1. Tutup Chrome sepenuhnya
  2. Jalankan Chrome dari konsol dengan "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" --js-flags="--allow-natives-syntax" itu untuk windows OS lain yang serupa.
  3. Buka konsol pengembang dan jalankan "%GetHeapUsage()". Jika Anda memulai Chrome dengan benar dengan opsi ini, sebuah nomor akan dicatat ke konsol, jika tidak Anda akan mendapatkan kesalahan sintaksis.

Dengan flag baris perintah ini, Anda dapat 'berbicara dengan mesin V8' dengan perintah yang dimulai dengan %, yang merupakan kesalahan sintaksis dalam JavaScript biasa. Daftar perintah V8 yang tersedia seperti ini diberikan dalam jawaban Paulus .

Ada %NeverOptimizeFunction()dalam daftar itu, yang merupakan sesuatu yang sepertinya harus saya panggil dan selesaikan. Sayangnya, fungsi itu tidak melakukan apa yang saya harapkan, seperti yang ditunjukkan pada tangkapan layar berikutnya.

lorem masih belum didefinisikan

((( Tautan lain dari jawaban Paul (modul node v8-native) tidak penting bagi kami di sini dalam konteks ini. Yang perlu dilakukan hanyalah membungkus satu-liner di sekitar panggilan fungsi "%" sehingga kode tidak macet) browser yang bukan v8.)))

(((Saya ingat saat ini berhasil (ketika optimasi ini belum ditemukan / diimplementasikan). Saya tidak tahu berapa lama yang lalu. Sepuluh tahun? 15 tahun? Sesuatu seperti itu. Apa versi Chrome terakhir (jika apa saja) dan apa versi firefox terakhir (lebih yakin di sini bahwa itu ada) di mana Anda bisa melakukannya? Ini tidak akan memberi Anda karunia, tetapi itu akan membuat Anda mendapatkan suara positif, jika Anda kebetulan tahu dan mempostingnya sebagai jawaban .)))

SOLUSINYA

TERIMA KASIH PETR SRNICEK

memperbaiki hacky

PERTANYAAN BARU

Meskipun solusi Petr banyak membantu, itu tidak sempurna. Pertanyaan ini terlalu panjang, jadi saya memposting pertanyaan baru tentang bagaimana solusi Petr dapat ditingkatkan. (Tentu saja saya dapat mengedit pertanyaan ini di sini, tetapi itu akan terasa "tidak historis", jika Anda tahu apa yang saya maksud.)


konsekuensi yang tidak diinginkan, bab kesepuluhandone. optimasi ini memiliki efek negatif pada gaya pengkodean saya. Saya menemukan diri saya menggunakan yang lama untuk loop (bukan .map, .forEach, .reduce) lebih dari yang saya lakukan, hanya saja saya menghindari masalah ini.
mathheadinclouds

The v8-nativesperpustakaan hanya membungkus% panggilan penting dalam kode di perpustakaan sederhana yang harus noopsdi browser atau node yang tidak dimulai pada --allow-pribumi-sintaks khusus ..
Natanael

Saya menjalankan beberapa tes, fungsi 'bodyOnLoad' tidak dioptimalkan lagi; jadi menggunakan perintah internal untuk mencoba dan memaksanya untuk tidak mengoptimalkan tidak melakukan apa-apa.
Nathanael

@Nathanael: Panggilan penting adalah %NeverOptimizeFunction(foo)saya hanya memanggilnya juga untuk bodyOnload, "hanya karena", berpikir "baik, itu tidak akan sakit". Masalahnya adalah bahwa fooTIDAK dioptimalkan seperti yang saya harapkan. Variabel loremtidak terlihat. Katakanlah saya ingin menulis beberapa kode yang akan masuk ke fungsi foo. Alih-alih mengetiknya ke editor teks saya, saya mengetiknya ke konsol dev (saat debugger duduk di foo), lihat apakah itu melakukan apa yang saya inginkan, dan kemudian salin / tempel dari konsol ke editor teks saya. Itulah bagaimana saya suka bekerja. Dan tidak bisa. Karena optimasi. Mendapatkan?
mathheadinclouds

1
Saya menghabiskan beberapa percobaan kami dengan berbagai --js-flags(termasuk beberapa yang berhubungan dengan TurboFan ) serta dengan beberapa perintah asli V8 sebelum Paul1365972 memposting jawabannya tetapi saya tidak dapat mencapai perilaku yang diinginkan. Saya percaya bahwa pendekatan ini mungkin jalan buntu. Mungkin bermanfaat untuk menambahkan [v8]tag pada pertanyaan ini. Seseorang dengan pemahaman mendalam tentang cara kerja V8 dalam mungkin dapat mengklarifikasi apakah ini cara untuk pergi atau mungkin mengarahkan Anda ke arah yang benar.
Petr Srníček

Jawaban:


2

Anda bisa mendapatkan akses ke semua variabel dengan membungkus pernyataan debugger dalam eval seperti ini: eval("debugger;");. Solusi peretasan ini menambahkan fungsi anonim lain ke tumpukan panggilan dan jelas tidak berguna untuk breakpoint yang ditetapkan secara manual di DevTools.

Ini tampaknya bukan solusi yang sangat baik, tetapi karena ini adalah satu-satunya yang mencapai perilaku yang diinginkan sejauh ini, saya mempostingnya sebagai jawaban.


agak mengejutkan saya bahwa ini bekerja. Anda tahu, saya mencoba mengetikkan eval ("lorem"), dan memberikan kesalahan "lorem tidak didefinisikan" yang sama. Tidak masuk akal bagi saya bahwa mengetik eval ("lorem") di konsol (ketika pada pernyataan debugger di function foo) harus melakukan sesuatu yang berbeda dari apa yang dilakukan eval ("debugger") - harapkan, cetak "ipsum" ke konsol. Tetapi mereka sangat berbeda. Aneh.
mathheadinclouds

Itu adalah pekerjaan yang menarik. Agak gila, karena Anda tidak dapat keluar dari pernyataan debugger (Anda hanya perlu secara manual beralih ke file sumber) jika tidak, Anda kehilangan seluruh tumpukan dan kembali ke fungsi yang disebut eval; membuat Anda tumpukan berkurang kehilangan konteks lainnya.
Nathanael

seseorang dapat memodifikasi trik ini dengan demikian: alih-alih eval ("debugger"), masukkan eval ("") - tetapi banyak dari mereka, didistribusikan di seluruh kode, di mana pun Anda berpikir Anda mungkin menginginkan 'breakpoint diperpanjang'. Anda kemudian dapat menetapkan breakpoint (dengan alat dev) di mana salah satu pernyataan eval ('') berada, dan begitu Anda berhenti di sana, Anda melakukan "melangkah ke". Saya sedang mempertimbangkan untuk menulis sedikit transpiler (kata besar untuk hal kecil yang saya lakukan) menempatkan pernyataan itu di awal setiap fungsi. stackoverflow.com/questions/59159996/...
mathheadinclouds

Saya baru saja mencoba mengganti eval ("debugger") dengan eval (); debugger, dan mendapat hasil berbeda, tergantung penggunaan firefox atau chrome. i.stack.imgur.com/wy5WT.png
mathheadinclouds

3

Google Chrome menggunakan V8 JS-Engine, Anda dapat mengaktifkan panggilan asli ke sana dengan flag --allow-natives-syntax, ini memperlihatkan banyak fungsi debug yang berguna (daftar lengkap di sini ) seperti yang Anda cari:% NeverOptimizeFunction () . Tanpa tanda ini, panggilan ini akan menjadi sintaksis ilegal, jadi berhati-hatilah saat menggunakan (atau gunakan pustaka v8-Natives ).

Untuk mengaktifkan fitur ini cukup buka chrome dengan --js-flags = "- allow-natives-syntax" (hanya gunakan ini untuk debugging situs web tepercaya, karena ini dapat memberikan akses kode js yang tidak terpercaya ke hal-hal yang Anda benar-benar tidak ingin melakukannya. memiliki akses ke).


Terima kasih. Silakan baca pertanyaan saya yang diperbarui. Sepertinya Anda sudah memiliki solusinya di sini, tetapi saya perlu klarifikasi lagi untuk mewujudkannya. Jika ini berhasil, Anda tentu layak mendapat hadiah.
mathheadinclouds

tl; dr gunakan --js-flags = "- allow-natives-syntax" sebagai gantinya. Untuk mengaktifkan fitur, V8 JS-Engine harus dimulai dengan flag --allow-natives-syntax, namun Anda tidak dapat memulainya secara langsung, ini adalah pekerjaan chrome. Jadi, Anda harus memberi tahu chrome untuk menghidupkan mesin dengan benderanya, bagaimana Anda melakukannya? Cukup lewati flag engine yang disebutkan melalui --js-flags = <your flag here> to chrome.
Paul1365972

nggak. Hanya mencobanya sekali lagi, untuk menjadi satu sisi yang aman. Saya telah mencoba keduanya --allow-natives-syntaxdan --js-flags="--allow-natives-syntax"beberapa kali sebagai "hal yang saya ketik setelah 'chrome' di konsol sistem operasi". Jika saya tidak mencoba semua ini sendiri, saya juga akan berpikir kesalahan ketik adalah penjelasan yang paling mungkin. Saya membuat tangkapan layar lain. i.stack.imgur.com/7cpPP.png Lihat salah ketik? Tolong beri saya jawaban yang jujur: apakah Anda baru saja "membaca dan memahami artikel" (menjadi jelas, tidak ada yang salah dengan itu, jika Anda tidak mengklaim lebih), atau apakah Anda benar-benar mencoba semua itu di komputer Anda? thx
mathheadinclouds

tebakan saja: mungkinkah saya tidak menjalankan chrome executable dengan opsi itu, tetapi saya mengkompilasi sumber chrome C ++ (atau apa pun) dengan opsi itu?
mathheadinclouds

1
Itu aneh saya baru saja mengujinya dan itu bekerja dengan baik, tidak perlu kompilasi. Saya hanya akan menulis dengan tepat apa yang saya lakukan sehingga tidak ada kesalahpahaman. 1. Tutup Chrome sepenuhnya 2. Jalankan Chrome dari konsol dengan "C: / Program Files (x86) /Google/Chrome/Application/chrome.exe" --js-flags = "- allow-natives-syntax" 3. Buka pengembang konsol dan jalankan "% GetHeapUsage ()" untuk menguji apakah semuanya berfungsi
Paul1365972

0

Saya sangat berharap pertanyaan ini memiliki jawaban NYATA. Yang berikut ini bukan jawaban yang nyata, itu darurat. Saya menulis alat bantu yang Anda dapat membuat kode pembantu bodoh dari formulir if (false) { console.log(variables, from, closures); }(lihat screenshot di pertanyaan) menggunakan analisis statis - Anda sisipkan dalam kode Anda, pernyataan bodoh dibuat, Anda dapat menyalinnya, maka Anda tidak perlu untuk mengetiknya. Saya tidak tahu apakah itu banyak membantu, karena semua menyalin dan menempel ini juga membutuhkan waktu, tetapi itulah yang saya dapatkan.

tangkapan layar

biola

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.