Jangan gunakan eval
kecuali Anda benar-benar positif tidak punya pilihan lain.
Seperti yang telah disebutkan, menggunakan sesuatu seperti ini akan menjadi cara terbaik untuk melakukannya:
window["functionName"](arguments);
Namun, itu tidak akan berfungsi dengan fungsi namespace'd:
window["My.Namespace.functionName"](arguments); // fail
Ini adalah bagaimana Anda akan melakukan itu:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
Untuk membuatnya lebih mudah dan memberikan fleksibilitas, berikut adalah fungsi kenyamanan:
function executeFunctionByName(functionName, context /*, args */) {
var args = Array.prototype.slice.call(arguments, 2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(context, args);
}
Anda akan menyebutnya seperti ini:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Catatan, Anda dapat meneruskan dalam konteks apa pun yang Anda inginkan, jadi ini akan melakukan hal yang sama seperti di atas:
executeFunctionByName("Namespace.functionName", My, arguments);
My.Namespace.functionName()
,this
akan merujuk keMy.Namespace
objek. Tetapi ketika Anda meneleponexecuteFunctionByName("My.Namespace.functionName", window)
, tidak ada carathis
untuk merujuk hal yang sama. Mungkin harus menggunakan namespace terakhir sebagai ruang lingkup, atauwindow
jika tidak ada ruang nama. Atau Anda bisa mengizinkan pengguna untuk menentukan ruang lingkup sebagai argumen.Hanya berpikir saya akan memposting versi yang sedikit diubah dari fungsi Jason Bunting yang sangat membantu .
Pertama, saya telah menyederhanakan pernyataan pertama dengan menyediakan parameter kedua ke slice () . Versi asli berfungsi dengan baik di semua browser kecuali IE.
Kedua, saya telah mengganti ini dengan konteks dalam pernyataan pengembalian; jika tidak, ini selalu menunjuk ke jendela ketika fungsi target dieksekusi.
sumber
Jawaban untuk pertanyaan lain ini menunjukkan kepada Anda bagaimana melakukannya: Javascript setara dengan penduduk lokal Python ()?
Pada dasarnya, Anda bisa mengatakannya
atau seperti yang banyak disarankan orang lain, Anda bisa menggunakan eval:
meskipun ini sangat tidak aman kecuali jika Anda benar-benar yakin dengan apa yang Anda evaluasi.
sumber
Bisakah kamu tidak melakukan ini saja:
Anda juga dapat menjalankan JavaScript lain menggunakan metode ini.
sumber
eval("My.Namespace.functionName()");
?var codeToExecute = "return My.Namespace.functionName()";
Saya pikir cara yang elegan untuk melakukan ini adalah dengan mendefinisikan fungsi Anda dalam objek hash. Kemudian Anda dapat memiliki referensi ke fungsi-fungsi tersebut dari hash menggunakan string. misalnya
Maka Anda dapat menelepon:
Di mana customFunction akan menjadi string yang cocok dengan fungsi yang didefinisikan dalam objek Anda.
sumber
Dengan ES6 Anda dapat mengakses metode kelas dengan nama:
hasilnya adalah:
sumber
Object.create()
. const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2Dua hal:
menghindari eval, itu sangat berbahaya dan lambat
kedua tidak masalah di mana fungsi Anda ada, "global" -ness tidak relevan.
x.y.foo()
dapat diaktifkan melaluix.y['foo']()
ataux['y']['foo']()
atau bahkanwindow['x']['y']['foo']()
. Anda dapat rantai tanpa batas seperti ini.sumber
Semua jawaban mengasumsikan bahwa fungsi dapat diakses melalui lingkup global (jendela). Namun, OP tidak membuat asumsi ini.
Jika fungsi hidup dalam lingkup lokal (alias penutupan) dan tidak direferensikan oleh beberapa objek lokal lainnya, sial: Anda harus menggunakan
eval()
AFAIK, lihat secara dinamis panggil fungsi lokal di javascriptsumber
Anda hanya perlu mengubah string Anda menjadi sebuah pointer
window[<method name>]
. contoh:dan sekarang Anda bisa menggunakannya seperti pointer.
sumber
Berikut adalah kontribusi saya untuk jawaban yang sangat baik dari Jason Bunting / Alex Nazarov, di mana saya menyertakan pengecekan kesalahan yang diminta oleh Crashalot.
Mengingat pembukaan ini (dibuat-buat):
maka fungsi berikut:
akan memungkinkan Anda untuk memanggil fungsi javascript dengan nama yang disimpan dalam string, baik namespace atau global, dengan atau tanpa argumen (termasuk objek Array), memberikan umpan balik pada setiap kesalahan yang ditemukan (mudah-mudahan menangkapnya).
Output sampel menunjukkan cara kerjanya:
sumber
if( typeof context[ functionName ] !== 'function' )
karena konteks - jendela - didefinisikan, adalah objek dan array, tetapi jendela ['abcd'] tidak ada sebagaimana diidentifikasi sebagai masalah dalam yang diterima jawaban:window["My.Namespace.functionName"](arguments); // fail
Tergantung di mana Anda berada, Anda juga dapat menggunakan:
atau, dalam simpuljs
sumber
Jika Anda ingin memanggil fungsi suatu objek, bukan fungsi global dengan
window["functionName"]
. Anda bisa melakukannya seperti;Contoh:
sumber
HATI-HATI!!!
Seseorang harus mencoba untuk menghindari memanggil fungsi dengan string dalam JavaScript karena dua alasan:
Alasan 1: Beberapa kode obfuscator akan merusak kode Anda karena mereka akan mengubah nama fungsi, membuat string tidak valid.
Alasan 2: Jauh lebih sulit untuk mempertahankan kode yang menggunakan metodologi ini karena jauh lebih sulit untuk menemukan penggunaan metode yang disebut dengan string.
sumber
Berikut ini adalah pendekatan Es6 saya yang memungkinkan Anda untuk memanggil fungsi Anda dengan namanya sebagai string atau nama fungsinya dan juga memungkinkan Anda untuk meneruskan sejumlah argumen ke berbagai jenis fungsi:
sumber
Terkejut melihat tidak disebutkannya setTimeout.
Untuk menjalankan fungsi tanpa argumen:
Untuk menjalankan fungsi dengan argumen:
Untuk menjalankan fungsi namespace secara mendalam:
sumber
runMe
dengan beberapa argumen.Jadi, seperti kata orang lain, pasti pilihan terbaik adalah:
Dan seperti yang dikatakan Jason Bunting , itu tidak akan berfungsi jika nama fungsi Anda menyertakan objek:
Jadi, inilah versi saya dari suatu fungsi yang akan menjalankan semua fungsi dengan nama (termasuk objek atau tidak):
sumber
Solusi OOP yang lebih ...
sumber
Satu lagi detail tentang posting Jason dan Alex. Saya merasa bermanfaat untuk menambahkan nilai default ke konteks. Masukkan saja
context = context == undefined? window:context;
di awal fungsi. Anda dapat mengubahwindow
ke apa pun konteks pilihan Anda, dan kemudian Anda tidak perlu memasukkan variabel yang sama setiap kali Anda menyebutnya dalam konteks default Anda.sumber
Untuk menambah jawaban Jason Bunting, jika Anda menggunakan nodejs atau sesuatu (dan ini juga berfungsi dalam doms,), Anda bisa menggunakan
this
alih-alihwindow
(dan ingat: eval itu jahat :sumber
Ada hal yang sangat mirip dalam kode saya. Saya memiliki string yang dihasilkan server yang berisi nama fungsi yang harus saya sampaikan sebagai panggilan balik untuk perpustakaan pihak ke-3. Jadi saya punya kode yang mengambil string dan mengembalikan "pointer" ke fungsi, atau nol jika tidak ditemukan.
Solusi saya sangat mirip dengan " fungsi yang sangat membantu Jason Bunting " * , meskipun tidak otomatis dieksekusi, dan konteksnya selalu di jendela. Tetapi ini dapat dengan mudah dimodifikasi.
Semoga ini bisa membantu seseorang.
sumber
Ada juga beberapa cara yang sangat membantu.
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
sumber
Saya tidak bisa menolak menyebutkan trik lain, yang membantu jika Anda memiliki sejumlah argumen yang tidak diketahui yang juga diteruskan sebagai bagian dari string yang berisi nama fungsi. Sebagai contoh:
var annoyingstring = 'call_my_func(123, true, "blah")';
Jika Javascript Anda berjalan pada halaman HTML, yang Anda butuhkan hanyalah tautan tak terlihat; Anda dapat melewatkan string ke dalam
onclick
atribut, dan memanggilclick
metode.<a href="#" id="link_secret"><!-- invisible --></a>
Atau buat
<a>
elemen saat runtime.sumber
Cara termudah adalah mengaksesnya seperti memiliki elemen
sama dengan
sumber
Anda dapat memanggil fungsi javascript di dalam
eval("functionname as string")
keduanya. Seperti di bawah ini: (eval adalah fungsi javascript murni)Contoh kerja: https://jsfiddle.net/suatatan/24ms0fna/4/
sumber
Ini bekerja untuk saya:
Saya harap ini berhasil.
sumber
Saya tidak berpikir Anda perlu fungsi perantara yang rumit atau eval atau bergantung pada variabel global seperti jendela:
Ini juga akan berfungsi dengan fungsi yang diimpor:
sumber
Tanpa menggunakan
eval('function()')
Anda bisa membuat fungsi baru menggunakannew Function(strName)
. Kode di bawah ini diuji menggunakan FF, Chrome, IE.sumber
sumber
Terlihat dasar:
Ada jenis fungsi lainnya adalah kelas dan lihat contoh nils petersohn
sumber
Terima kasih atas jawaban yang sangat membantu. Saya menggunakan fungsi Jason Bunting dalam proyek saya.
Saya memperpanjang untuk menggunakannya dengan batas waktu opsional, karena cara normal untuk mengatur batas waktu tidak akan berfungsi. Lihat pertanyaan abhishekisnot
sumber