Chris B
Chris B

Reputation: 5441

How do I call a dynamically-named method in Javascript?

I am working on dynamically creating some JavaScript that will be inserted into a web page as it's being constructed.

The JavaScript will be used to populate a listbox based on the selection in another listbox. When the selection of one listbox is changed it will call a method name based on the selected value of the listbox.

For example:

Listbox1 contains:

If Colours is selected then it will call a populate_Colours method that populates another listbox.

To clarify my question: How do I make that populate_Colours call in JavaScript?

Upvotes: 144

Views: 191451

Answers (13)

Just do it

class User {
  getName() {   
    return "dilo";
  }
}

let user = new User();
let dynamicMethod = 'getName';
console.log(user[dynamicMethod]()); //dilo

Upvotes: 4

Jonatas Mendes
Jonatas Mendes

Reputation: 63

// FUNCTIONS
const funcs = {

  func1() {
    console.log('func1 accessed');
  },

  func2() {
    console.log('func2 accessed');
  }

}

// DYNAMIC FUNCTION NAME
const nameFunc = 'func2';

// DYNAMIC ACCESS TO FUNCTIONS
funcs[nameFunc]();

Upvotes: 0

proseosoc
proseosoc

Reputation: 1354

Try These

Call Functions With Dynamic Names, like this:

let dynamic_func_name = 'alert';
(new Function(dynamic_func_name+'()'))()

with parameters:

let dynamic_func_name = 'alert';
let para_1 = 'HAHAHA';
let para_2 = 'ABCD';
(new Function(`${dynamic_func_name}('${para_1}','${para_2}')`))()

Run Dynamic Code:

let some_code = "alert('hahaha');";
(new Function(some_code))()

Upvotes: 0

Shakir El Amrani
Shakir El Amrani

Reputation: 330

A simple function to call a function dynamically with parameters:

this.callFunction = this.call_function = function(name) {
    var args = Array.prototype.slice.call(arguments, 1);
    return window[name].call(this, ...args);
};

function sayHello(name, age) {
    console.log('hello ' + name + ', your\'e age is ' + age);
    return some;
}

console.log(call_function('sayHello', 'john', 30)); // hello john, your'e age is 30

Upvotes: 0

GorvGoyl
GorvGoyl

Reputation: 49210

I would recommend NOT to use global / window / eval for this purpose.
Instead, do it this way:

define all methods as properties of Handler:

var Handler={};

Handler.application_run = function (name) {
console.log(name)
}

Now call it like this

var somefunc = "application_run";
Handler[somefunc]('jerry');

Output: jerry


Case when importing functions from different files

import { func1, func2 } from "../utility";

const Handler= {
  func1,
  func2
};

Handler["func1"]("sic mundus");
Handler["func2"]("creatus est");

Upvotes: 54

Kenan Banks
Kenan Banks

Reputation: 211982

Assuming the populate_Colours method is in the global namespace, you may use the following code, which exploits both that all object properties may be accessed as though the object were an associative array, and that all global objects are actually properties of the window host object.

var method_name = "Colours";
var method_prefix = "populate_";

// Call function:
window[method_prefix + method_name](arg1, arg2);

Upvotes: 250

Tim
Tim

Reputation: 1072

I wouldn't recommend using the window as some of the other answers suggest. Use this and scope accordingly.

this['yourDynamicFcnName'](arguments);

Another neat trick is calling within different scopes and using it for inheritance. Let's say you had nested the function and want access to the global window object. You could do this:

this['yourDynamicFcnName'].call(window, arguments);

Upvotes: 6

David Spillett
David Spillett

Reputation: 1421

As Triptych points out, you can call any global scope function by finding it in the host object's contents.

A cleaner method, which pollutes the global namespace much less, is to explicitly put the functions into an array directly like so:

var dyn_functions = [];
dyn_functions['populate_Colours'] = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions['populate_Shapes'](1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions.populate_Shapes(1, 2);

This array could also be a property of some object other than the global host object too meaning that you can effectively create your own namespace as many JS libraries such as jQuery do. This is useful for reducing conflicts if/when you include multiple separate utility libraries in the same page, and (other parts of your design permitting) can make it easier to reuse the code in other pages.

You could also use an object like so, which you might find cleaner:

var dyn_functions = {};
dyn_functions.populate_Colours = function (arg1, arg2) { 
                // function body
           };
dyn_functions['populate_Shapes'] = function (arg1, arg2) { 
                // function body
           };
// calling one of the functions
var result = dyn_functions.populate_Shapes(1, 2);
// this works as well due to the similarity between arrays and objects
var result2 = dyn_functions['populate_Shapes'](1, 2);

Note that with either an array or an object, you can use either method of setting or accessing the functions, and can of course store other objects in there too. You can further reduce the syntax of either method for content that isn't that dynamic by using JS literal notation like so:

var dyn_functions = {
           populate_Colours:function (arg1, arg2) { 
                // function body
           };
         , populate_Shapes:function (arg1, arg2) { 
                // function body
           };
};

Edit: of course for larger blocks of functionality you can expand the above to the very common "module pattern" which is a popular way to encapsulate code features in an organised manner.

Upvotes: 50

OXiGEN
OXiGEN

Reputation: 2399

Within a ServiceWorker or Worker, replace window with self:

self[method_prefix + method_name](arg1, arg2);

Workers have no access to the DOM, therefore window is an invalid reference. The equivalent global scope identifier for this purpose is self.

Upvotes: 6

Aylian Craspa
Aylian Craspa

Reputation: 466

Here is a working and simple solution for checking existence of a function and triaging that function dynamically by another function;

Trigger function

function runDynmicFunction(functionname){ 

    if (typeof window[functionname] == "function"  ) { //check availability

        window[functionname]("this is from the function it "); //run function and pass a parameter to it
    }
}

and you can now generate the function dynamically maybe using php like this

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

now you can call the function using dynamically generated event

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynmicFunction(\"".$name_frm_somware."\");'>";

?>

the exact HTML code you need is

<input type="button" value="Button" onclick="runDynmicFunction('runThis_func');">

Upvotes: -2

Gilberto
Gilberto

Reputation: 35

Try with this:

var fn_name = "Colours",
fn = eval("populate_"+fn_name);
fn(args1,argsN);

Upvotes: -4

Simon
Simon

Reputation: 226

you can do it like this:

function MyClass() {
    this.abc = function() {
        alert("abc");
    }
}

var myObject = new MyClass();
myObject["abc"]();

Upvotes: 20

mathi
mathi

Reputation: 1147

Hi try this,

 var callback_function = new Function(functionName);
 callback_function();

it will handle the parameters itself.

Upvotes: 1

Related Questions