Bagaimana menjalankan fungsi JavaScript ketika saya memiliki namanya sebagai string


1051

Saya memiliki nama fungsi dalam JavaScript sebagai string. Bagaimana cara mengonversinya menjadi fungsi penunjuk sehingga saya dapat memanggilnya nanti?

Bergantung pada situasinya, saya mungkin perlu memberikan berbagai argumen ke dalam metode ini juga.

Beberapa fungsi dapat berupa namespace.namespace.function(args[...]).

Jawaban:


1439

Jangan gunakan evalkecuali 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);

4
Anda tahu Anda tidak perlu seluruh "func" membangun? "context.apply" sendiri baik
annakata

16
Tentu, saya tahu itu - tetapi cara saya menulis fungsi memberikan kejelasan bagi mereka yang membacanya yang mungkin tidak sepenuhnya grok apa yang terjadi. Saya menulis fungsi ini untuk menyadari orang yang membacanya mungkin perlu bantuan. Saya akan memberikan alternatif lain, karena Anda bertanya ...
Jason Bunting

108
Gores itu - kodenya cukup jelas dan yang tahu, tahu. Jika Anda seperti saya, dan tahu apa yang Anda lakukan, Anda bisa melakukan perubahan sendiri jika menggunakan kode ini. Stack Overflow adalah untuk mendidik orang lain, dan saya pikir kode saya lebih mudah bagi pemula untuk mengerti. Terimakasih Meskipun!
Jason Bunting

4
Apakah ada situasi ketika window ["funcName"] akan kembali tidak terdefinisi? Itulah masalah yang saya alami saat ini. Kode panggilan dan fungsinya didefinisikan dalam dua file js yang terpisah. Saya mencoba menambahkannya ke file yang sama tetapi tidak ada bedanya.
codemonkey

5
Saya pikir ada masalah di sini. Saat Anda menelepon My.Namespace.functionName(), thisakan merujuk ke My.Namespaceobjek. Tetapi ketika Anda menelepon executeFunctionByName("My.Namespace.functionName", window), tidak ada cara thisuntuk merujuk hal yang sama. Mungkin harus menggunakan namespace terakhir sebagai ruang lingkup, atau windowjika tidak ada ruang nama. Atau Anda bisa mengizinkan pengguna untuk menentukan ruang lingkup sebagai argumen.
JW.

100

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.

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);
}

Tidak ada pemeriksaan untuk melihat apakah "functionName" benar-benar ada?
Crashalot

Saya pikir jawaban Mac diremehkan. Saya bukan ahli tetapi tampaknya dipikirkan dengan baik dan kuat.
Martin Hansen Lennox

65

Jawaban untuk pertanyaan lain ini menunjukkan kepada Anda bagaimana melakukannya: Javascript setara dengan penduduk lokal Python ()?

Pada dasarnya, Anda bisa mengatakannya

window["foo"](arg1, arg2);

atau seperti yang banyak disarankan orang lain, Anda bisa menggunakan eval:

eval(fname)(arg1, arg2);

meskipun ini sangat tidak aman kecuali jika Anda benar-benar yakin dengan apa yang Anda evaluasi.


6
bentuk pertama jauh lebih disukai
annakata

19
Hanya gunakan eval sebagai pilihan terakhir, ketika semuanya gagal.
Jason Bunting

1
Itu adalah ... tetapi apakah ini akan bekerja dengan fungsi-fungsi seperti ini: xyz (args)?
Kieron

@keiron: ya. lihat jawaban saya di bawah ini
annakata

55

Bisakah kamu tidak melakukan ini saja:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

Anda juga dapat menjalankan JavaScript lain menggunakan metode ini.


3
bekerja ketika bahkan argumen dilewatkan dengan fungsi
adeel41

Bagaimana dengan fungsi yang dikembalikan?
Peter Denev

12
Bagaimana itu berbeda dari eval("My.Namespace.functionName()");?
developerbmw

@PeterDenev baru saja mengubah baris pertama kevar codeToExecute = "return My.Namespace.functionName()";
developerbmw

2
@developerbmw, berikut adalah jawaban stackoverflow.com/questions/4599857/…
Tejasvi Hegde

48

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

var customObject = {
  customFunction: function(param){...}
};

Maka Anda dapat menelepon:

customObject['customFunction'](param);

Di mana customFunction akan menjadi string yang cocok dengan fungsi yang didefinisikan dalam objek Anda.


@ibsenv, terima kasih atas komentar Anda untuk membantu saya mengidentifikasi respons ini sebagai yang terbaik. Saya membuat array objek fungsi dan pada gilirannya menggunakannya untuk membuat array deferred.promises. Saya menaruh beberapa kode contoh di bawah ini. (Saya tidak ingin membuat balasan baru dan meminjam tanggapan Ruben.)
user216661

function getMyData (arrayOfObjectsWithIds) {var functionArray = arrayOfObjectsWithIds.map (fungsi (nilai) {return {myGetDataFunction: MyService.getMyData (value.id)};}) var janji = functionArray.map (fungsi (get $ fungsi) q.defer (); getDataFunction.myGetDataFunction.success (fungsi (data) {deferred.resolve (data)}). error (fungsi (kesalahan) {deferred.reject ();}); return deferred.promise;}); $ q.all (janji) .then (function (dataArray) {// do stuff})};
user216661

Ini berfungsi sangat baik, saya hanya menambahkan garis bawah / lodash untuk memverifikasi jika itu sebuah fungsi. Dan kemudian jalankan
elporfirio

35

Dengan ES6 Anda dapat mengakses metode kelas dengan nama:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

hasilnya adalah:

1
2

1
MURNI javascript terbaik ... Ya Tuhan .. hapus kelas tidak berfungsi dan ok. Terima kasih!
KingRider

1
Ini adalah hal yang saya cari sejak lama. Terima kasih!
PaladiN

ES2015 tidak ada hubungannya di sini. Anda dapat mencapai tujuan yang sama menggunakan objek murni, atau delegasi prototipe via Object.create(). const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2
sminutoli

1
Ini emas !!! Saya terkejut saya tidak pernah memikirkan hal ini sebelumnya. Bagus!!!
thxmike

Saya juga berpikir ini adalah cara paling rapi untuk mencapai tujuan kami.
Chris Jung

24

Dua 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 melalui x.y['foo']()atau x['y']['foo']()atau bahkan window['x']['y']['foo'](). Anda dapat rantai tanpa batas seperti ini.


1
tetapi Anda tidak dapat melakukan window ['xyz'] () untuk memanggil xyz ()
nickf

17

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 javascript


2
Bung (atau dudette), terima kasih banyak untuk menunjukkannya! Saya pikir saya akan menjadi gila sebentar.
Funktr0n

13

Anda hanya perlu mengubah string Anda menjadi sebuah pointer window[<method name>]. contoh:

var function_name = "string";
function_name = window[function_name];

dan sekarang Anda bisa menggunakannya seperti pointer.


Ini sepertinya cara yang jauh lebih aman.
James Poulose

12

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):

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

maka fungsi berikut:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

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:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

Tak tahu ... itu upaya yang sangat bagus, sejelas itu. Tapi kedengarannya seperti "terlalu luas" bagi saya ...
TechNyquist

2
Hah? SO adalah platform pertanyaan / jawaban / pengajaran. Saya dengan senang hati akan memberikan semua contoh yang bisa saya pikirkan untuk mudah-mudahan menyampaikan iluminasi. Bagi saya, itulah intinya .
Mac

Jika Anda tetap menggunakan functionName, mengapa tidak menggunakannya saja?
data

Ini tidak berhasil untuk saya. Saya memiliki fungsi namespace abcd di mana d adalah nama fungsi. panggilan executeFunctionByName ("abcd", jendela) gagal pada baris yang memeriksa 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
akousmata

12

Tergantung di mana Anda berada, Anda juga dapat menggunakan:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

atau, dalam simpuljs

global["funcname"]()

9

Jika Anda ingin memanggil fungsi suatu objek, bukan fungsi global dengan window["functionName"]. Anda bisa melakukannya seperti;

var myObject=new Object();
myObject["functionName"](arguments);

Contoh:

var now=new Date();
now["getFullYear"]()

8

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.


7

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:

function fnCall(fn, ...args)
{
  let func = (typeof fn =="string")?window[fn]:fn;
  if (typeof func == "function") func(...args);
  else throw new Error(`${fn} is Not a function!`);
}


function example1(arg1){console.log(arg1)}
function example2(arg1, arg2){console.log(arg1 + "  and   " + arg2)}
function example3(){console.log("No arguments!")}

fnCall("example1", "test_1");
fnCall("example2", "test_2", "test3");
fnCall(example3);
fnCall("example4"); // should raise an error in console


6

Terkejut melihat tidak disebutkannya setTimeout.

Untuk menjalankan fungsi tanpa argumen:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

Untuk menjalankan fungsi dengan argumen:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

Untuk menjalankan fungsi namespace secara mendalam:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

Ini tidak memberikan jawaban untuk pertanyaan itu. Untuk mengkritik atau meminta klarifikasi dari penulis, tinggalkan komentar di bawah postingan mereka - Anda selalu dapat mengomentari posting Anda sendiri, dan begitu Anda memiliki reputasi yang cukup, Anda akan dapat mengomentari setiap posting .
AstroCB

Silakan tambahkan contoh bagaimana Anda akan menelepon runMedengan beberapa argumen.
lexicore

1
@lexicore Saya memilih untuk dihapus dalam antrian ulasan, karena tidak jelas memberikan jawaban yang substansial untuk pertanyaan dan itu bernilai kecil saja.
AstroCB

1
Metode ini berpotensi memiliki kelemahan besar, karena menempatkan eksekusi pada akhir proses antrian, sehingga membuat panggilan ini tidak sinkron
PeterM

1
Saya suka jawaban ini, sepertinya berfungsi untuk kebutuhan saya.
Quintonn

3

Jadi, seperti kata orang lain, pasti pilihan terbaik adalah:

window['myfunction'](arguments)

Dan seperti yang dikatakan Jason Bunting , itu tidak akan berfungsi jika nama fungsi Anda menyertakan objek:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

Jadi, inilah versi saya dari suatu fungsi yang akan menjalankan semua fungsi dengan nama (termasuk objek atau tidak):

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');


3
  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

Solusi OOP yang lebih ...


2

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 mengubah windowke apa pun konteks pilihan Anda, dan kemudian Anda tidak perlu memasukkan variabel yang sama setiap kali Anda menyebutnya dalam konteks default Anda.


2

Untuk menambah jawaban Jason Bunting, jika Anda menggunakan nodejs atau sesuatu (dan ini juga berfungsi dalam doms,), Anda bisa menggunakan thisalih-alih window(dan ingat: eval itu jahat :

this['fun'+'ctionName']();

2

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.

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}


1

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 onclickatribut, dan memanggil clickmetode.

<a href="#" id="link_secret"><!-- invisible --></a>

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

Atau buat <a>elemen saat runtime.


Solusi kreatif, tetapi ini tidak akan berfungsi untuk argumen tipe objek atau array.
Dennis Heiden

1
Ini menggunakan eval di bawah tenda ... Dan benar-benar berbelit-belit untuk melakukannya
Juan Mendes

1

Cara termudah adalah mengaksesnya seperti memiliki elemen

window.ClientSideValidations.forms.location_form

sama dengan

window.ClientSideValidations.forms['location_form']

1

Anda dapat memanggil fungsi javascript di dalam eval("functionname as string")keduanya. Seperti di bawah ini: (eval adalah fungsi javascript murni)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

Contoh kerja: https://jsfiddle.net/suatatan/24ms0fna/4/


Ini berfungsi dengan baik dan sangat sederhana
Carlos E

1
Dan juga sangat lambat.
Marco

1

Ini bekerja untuk saya:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

Saya harap ini berhasil.


1

Saya tidak berpikir Anda perlu fungsi perantara yang rumit atau eval atau bergantung pada variabel global seperti jendela:

function fun1(arg) {
  console.log(arg);
}

function fun2(arg) {
  console.log(arg);
}

const operations = {
  fun1,
  fun2
};

let temp = "fun1";

try {
  // You have to use square brackets property access
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
  // You can use variables
  operations[temp]("Hello World");
} catch (error) {
  console.error(error);
}

Ini juga akan berfungsi dengan fungsi yang diimpor:

// mode.js
export function fun1(arg) {
  console.log(arg);
}

export function fun2(arg) {
  console.log(arg);
}
// index.js
import { fun1, fun2 } from "./mod";

const operations = {
  fun1,
  fun2
};

try {
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
} catch (error) {
  console.error(error);
}

0

Tanpa menggunakan eval('function()') Anda bisa membuat fungsi baru menggunakan new Function(strName). Kode di bawah ini diuji menggunakan FF, Chrome, IE.

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

0
use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(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);
    }

1
Mengapa? Jawaban tanpa penjelasan kemungkinan besar tidak berguna.
Daniel W.

0

Terlihat dasar:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

Ada jenis fungsi lainnya adalah kelas dan lihat contoh nils petersohn


0

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

function executeFunctionByName(functionName, context, timeout /*, args */ ) {
	var args = Array.prototype.slice.call(arguments, 3);
	var namespaces = functionName.split(".");
	var func = namespaces.pop();
	for (var i = 0; i < namespaces.length; i++) {
		context = context[namespaces[i]];
	}
	var timeoutID = setTimeout(
		function(){ context[func].apply(context, args)},
		timeout
	);
    return timeoutID;
}

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

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.