简体   繁体   中英

Call JavaScript Function using object values as parameters

I have an object:

var obj = {
    foo: 'foo',
    bar: 'bar'
};

And I have a function:

var f = function(bar, foo) {
    // Do something with bar and foo
};

Is there a way I can dynamically call the function using the object, so that obj['foo'] is passed as the 'foo' parameter, and obj['bar'] is passed as the 'bar' parameter? Note that I may not know the actual names of the keys and values or the function argument names, the ones provided are just an example, so f.call(this, obj['bar'], obj['foo']); won't do.

Sure, in ES6

 var f = function({bar, foo}) { console.log('foo', foo, 'bar', bar) }; var obj = { foo: '11', bar: '22' }; f(obj) 

Based on deceze's comment, I managed to come up with a solution. I'm not exactly sure how fast it is, but it gets the job done. Improvements are welcome! Thanks for everyone's help.

I used this function from this answer :

function getParameterNames(fn){
    var fstr = fn.toString();
    return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi,'').replace(/\s/gi,'').split(',');
}

And made the following:

var obj = {
    foo: 'foo',
    bar: 'bar'
};

var f = function(bar, foo) {
    // Do something with bar and foo
};

var sortedArgs = [];
getParameterNames(f).forEach(function(item) {
    sortedArgs.push(args[item]);
});

f.apply(this, sortedArgs);

You could check if provided argument is object and then use destructuring

 var obj = { foo: 'foo', bar: 'bar' }; var f = function(foo, bar) { if(typeof arguments[0] == 'object') var {foo, bar} = arguments[0]; console.log('Foo: ' + foo); console.log('Bar: ' + bar) }; f(obj); f('lorem', 'ipsum'); 

You could bind the object to the function.

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

 var obj = { foo: 'foo', bar: 'bar' }, f = function(k) { console.log(this[k]); }.bind(obj); f('foo'); 

You can write a function which will wrap your function and use new function instead to get what you want.

 function wrapper(fn) { var fnString = fn.toString(); var fnRegex = /\\((.*)\\)/; var params = fnString .match(fnRegex)[1] .replace(/\\s/, '') .split(',') .filter(function(arg) { return arg; }); return function (o) { var args = params .map(function(arg) { return o[arg]; }); return fn.apply(null, args); } } // Example: your function. function yourFunc(foo, bar) { console.log('my foo: ' + foo); console.log('my bar: ' + bar); } // wrap your function and use new function instead. var enhancedFunc = wrapper(yourFunc); enhancedFunc({foo: 1, bar: 2}); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM