function main()
{
Hello();
}
function Hello()
{
// How do you find out the caller function is 'main'?
}
Apakah ada cara untuk mengetahui tumpukan panggilan?
javascript
callstack
Ray Lu
sumber
sumber
Jawaban:
Perhatikan bahwa fitur ini non-standar , dari
Function.caller
:Berikut ini adalah jawaban lama dari 2008, yang tidak lagi didukung dalam Javascript modern:
sumber
arguments.callee.caller.name
akan mendapatkan nama fungsi.'use strict';
mungkin membantu.arguments
BISA diakses dari dalam suatu fungsi dalam mode ketat, itu akan bodoh untuk mencabut itu. tidak hanya dari function.arguments dari luar. Juga, jika Anda memiliki argumen bernama, bentuk argumen [i] tidak akan melacak perubahan yang Anda buat ke versi bernama di dalam fungsi.StackTrace
Anda dapat menemukan seluruh jejak tumpukan menggunakan kode khusus browser. Hal yang baik adalah seseorang telah berhasil ; di sini adalah kode proyek di GitHub .
Namun tidak semua berita baik:
Sangat lambat untuk mendapatkan jejak tumpukan jadi berhati-hatilah (baca ini lebih lanjut).
Anda perlu mendefinisikan nama fungsi agar jejak stack dapat terbaca. Karena jika Anda memiliki kode seperti ini:
Google Chrome akan mengingatkan
... kls.Hello ( ...
tetapi sebagian besar peramban akan mengharapkan nama fungsi tepat setelah kata kuncifunction
dan akan memperlakukannya sebagai fungsi anonim. Chrome yang bahkan tidak dapat menggunakanKlass
nama jika Anda tidak memberikan namakls
ke fungsi.Dan omong-omong, Anda dapat beralih ke fungsi printStackTrace opsi
{guess: true}
tapi saya tidak menemukan perbaikan nyata dengan melakukan itu.Tidak semua browser memberi Anda informasi yang sama. Yaitu, parameter, kolom kode, dll.
Nama Fungsi Penelepon
Ngomong-ngomong, jika Anda hanya ingin nama fungsi pemanggil (di sebagian besar browser, tetapi tidak di IE) Anda dapat menggunakan:
Tetapi perhatikan bahwa nama ini akan menjadi nama setelah
function
kata kunci. Saya tidak menemukan cara (bahkan di Google Chrome) untuk mendapatkan lebih dari itu tanpa mendapatkan kode seluruh fungsi.Kode Fungsi Penelepon
Dan meringkas sisa jawaban terbaik (oleh Pablo Cabrera, nourdine, dan Greg Hewgill). Satu-satunya cross-browser dan hal yang benar-benar aman yang dapat Anda gunakan adalah:
Yang akan menampilkan kode fungsi pemanggil. Sayangnya, itu tidak cukup bagi saya, dan itulah sebabnya saya memberi Anda tips untuk StackTrace dan Nama fungsi penelepon (meskipun mereka bukan cross-browser).
sumber
Function.caller
per @ GregFunction.caller
tidak akan bekerja dalam mode ketat, namun.Saya tahu Anda menyebutkan "dalam Javascript", tetapi jika tujuannya adalah debugging, saya pikir lebih mudah untuk hanya menggunakan alat pengembang browser Anda. Ini adalah tampilannya di Chrome: Letakkan saja debugger tempat Anda ingin menyelidiki tumpukan.
sumber
Untuk rekap (dan membuatnya lebih jelas) ...
kode ini:
setara dengan ini:
Jelas bit pertama lebih portabel, karena Anda dapat mengubah nama fungsi, katakan dari "Halo" menjadi "Ciao", dan semuanya masih berfungsi.
Dalam yang terakhir, jika Anda memutuskan untuk refactor nama fungsi yang dipanggil (Halo), Anda harus mengubah semua kemunculannya :(
sumber
Anda bisa mendapatkan stacktrace lengkap:
Sampai penelepon
null
.Catatan: ini menyebabkan loop tak terbatas pada fungsi rekursif.
sumber
Saya biasanya menggunakan
(new Error()).stack
Chrome. Yang menyenangkan adalah bahwa ini juga memberi Anda nomor baris tempat pemanggil memanggil fungsi. The downside adalah bahwa ia membatasi panjang tumpukan hingga 10, itulah sebabnya saya datang ke halaman ini di tempat pertama.(Saya menggunakan ini untuk mengumpulkan callstacks di konstruktor tingkat rendah selama eksekusi, untuk melihat dan men-debug nanti, jadi menetapkan breakpoint tidak digunakan karena akan dipukul ribuan kali)
sumber
'use strict';
ada di tempat. Memberi saya info yang saya butuhkan - terima kasih!Jika Anda tidak akan menjalankannya di IE <11 maka console.trace () akan sesuai.
sumber
Anda dapat menggunakan Function.Caller untuk mendapatkan fungsi panggilan. Metode lama menggunakan argument.caller dianggap usang.
Kode berikut menggambarkan penggunaannya:
Catatan tentang argument.caller usang: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller
Sadarilah Function.caller adalah non-standar: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller
sumber
Cannot access caller property of a strict mode function
Saya akan melakukan ini:
sumber
sumber
arguments.callee.caller.toString()
Ini lebih aman untuk digunakan
*arguments.callee.caller
karenaarguments.caller
sudah usang ...sumber
arguments.callee
juga ditinggalkan dalam ES5, dan dihapus dalam mode ketat.arguments.callee
adalah solusi buruk untuk masalah yang kini telah diselesaikan dengan lebih baik developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Sepertinya ini adalah pertanyaan yang cukup terselesaikan tetapi saya baru-baru ini menemukan bahwa callee tidak diperbolehkan dalam 'mode ketat' jadi untuk penggunaan saya sendiri, saya menulis sebuah kelas yang akan mendapatkan jalur dari tempat ia dipanggil. Ini bagian dari lib pembantu kecil dan jika Anda ingin menggunakan kode standalone, ganti offset yang digunakan untuk mengembalikan jejak tumpukan pemanggil (gunakan 1 bukan 2)
sumber
function a(){ function b(){ function c(){ return ScriptPath(); } return c(); } return b(); } a()
di konsol (belum mencoba dalam file), tetapi tampaknya memiliki ide yang masuk akal. Bagaimanapun harus ditingkatkan untuk visibilitas.Coba akses ini:
sumber
Cukup konsol catat tumpukan kesalahan Anda. Anda kemudian bisa tahu bagaimana Anda dipanggil
sumber
Dalam mode ES6 dan Strict, gunakan yang berikut untuk mendapatkan fungsi Caller
Harap dicatat bahwa, baris di atas akan mengeluarkan pengecualian, jika tidak ada penelepon atau tidak ada tumpukan sebelumnya. Gunakan yang sesuai.
sumber
console.log((new Error()).stack.split("\n")[1].trim().split(" ")[1])
Pembaruan 2018
caller
dilarang dalam mode ketat . Berikut adalah alternatif menggunakanError
tumpukan (non-standar) .Fungsi berikut tampaknya melakukan pekerjaan di Firefox 52 dan Chrome 61-71 meskipun implementasinya membuat banyak asumsi tentang format logging dari dua browser dan harus digunakan dengan hati-hati, mengingat itu melemparkan pengecualian dan mungkin menjalankan dua regex pertandingan sebelum dilakukan.
sumber
Saya ingin menambahkan biola saya di sini untuk ini:
http://jsfiddle.net/bladnman/EhUm3/
Saya menguji ini adalah chrome, safari dan IE (10 dan 8). Bekerja dengan baik. Hanya ada 1 fungsi yang penting, jadi jika Anda takut dengan biola besar, baca di bawah ini.
Catatan: Ada cukup banyak "boilerplate" saya sendiri dalam biola ini. Anda dapat menghapus semua itu dan menggunakan split jika Anda mau. Ini hanya seperangkat fungsi yang sangat aman yang saya andalkan.
Ada juga templat "JSFiddle" di sana yang saya gunakan untuk banyak biola untuk sekadar bermain biola cepat.
sumber
String.prototype.trim = trim;
Jika Anda hanya ingin nama fungsinya dan bukan kodenya, dan menginginkan solusi independen-peramban, gunakan yang berikut ini:
Perhatikan bahwa hal di atas akan mengembalikan kesalahan jika tidak ada fungsi pemanggil karena tidak ada elemen [1] dalam array. Untuk menyiasatinya, gunakan di bawah ini:
sumber
Hanya ingin membiarkan Anda tahu bahwa pada PhoneGap / Android yang
name
doesnt tampaknya akan bekerja. Tetapiarguments.callee.caller.toString()
akan melakukan trik.sumber
Di sini, semuanya kecuali
functionname
dilucuticaller.toString()
, dengan RegExp.sumber
di sini adalah fungsi untuk mendapatkan stacktrace penuh :
sumber
jawaban heystewart dan jawaban JiarongWu keduanya menyebutkan bahwa
Error
objek memiliki akses kestack
.Ini sebuah contoh:
Browser yang berbeda menunjukkan tumpukan dalam format string yang berbeda:
Safari : Caller is: main@https://stacksnippets.net/js:14:8 Firefox : Caller is: main@https://stacksnippets.net/js:14:3 Chrome : Caller is: at main (https://stacksnippets.net/js:14:3) IE Edge : Caller is: at main (https://stacksnippets.net/js:14:3) IE : Caller is: at main (https://stacksnippets.net/js:14:3)
Sebagian besar browser akan mengatur stack
var stack = (new Error()).stack
. Di Internet Explorer tumpukan akan tidak ditentukan - Anda harus melempar pengecualian nyata untuk mengambil tumpukan.Kesimpulan: Ini mungkin untuk menentukan "utama" adalah penelepon untuk "Hello" menggunakan
stack
dalamError
objek. Bahkan itu akan bekerja dalam kasus di manacallee
/caller
pendekatannya tidak berfungsi. Ini juga akan menunjukkan konteks kepada Anda, yaitu file sumber dan nomor baris. Namun diperlukan upaya untuk membuat solusi lintas platform.sumber
Catatan Anda tidak dapat menggunakan Function.caller di Node.js, gunakan paket pemanggil-id sebagai gantinya. Sebagai contoh:
sumber
Coba kode berikut:
Bekerja untuk saya di Firefox-21 dan Chromium-25.
sumber
arguments.callee
telah ditinggalkan selama bertahun-tahun .Cara lain untuk mengatasi masalah ini adalah dengan hanya memberikan nama fungsi panggilan sebagai parameter.
Sebagai contoh:
Sekarang, Anda bisa memanggil fungsi seperti ini:
Contoh saya menggunakan cek kode nama fungsi, tetapi Anda dapat dengan mudah menggunakan pernyataan switch atau logika lain untuk melakukan apa yang Anda inginkan di sana.
sumber
Sejauh yang saya tahu, kami memiliki 2 cara untuk ini dari sumber yang diberikan seperti ini-
arguments.caller
Function.caller
Pikirkan jawaban Anda :).
sumber
Mengapa semua solusi di atas terlihat seperti ilmu roket. Sementara itu, seharusnya tidak lebih rumit dari cuplikan ini. Semua kredit untuk orang ini
Bagaimana Anda mengetahui fungsi pemanggil dalam JavaScript?
sumber
Saya mencoba menjawab pertanyaan dan hadiah saat ini dengan pertanyaan ini.
Karunia itu mengharuskan pemanggil diperoleh dalam mode ketat , dan satu-satunya cara saya bisa melihat ini dilakukan adalah dengan merujuk ke fungsi yang dinyatakan di luar mode ketat.
Sebagai contoh, berikut ini adalah non-standar tetapi telah diuji dengan versi sebelumnya (29/03/2016) dan saat ini (1 Agustus 2018) Chrome, Edge dan Firefox.
sumber
Jika Anda benar-benar membutuhkan fungsionalitas untuk beberapa alasan dan ingin itu kompatibel lintas-browser dan tidak khawatir untuk hal-hal yang ketat dan maju kompatibel kemudian berikan referensi ini:
sumber
Saya pikir potongan kode berikut mungkin bermanfaat:
Jalankan kode:
Log terlihat seperti ini:
sumber