[英]Invoke a Function with the Correct Parameters from an Object in JavaScript
Let's say I have an object that looks like this: 假设我有一个看起来像这样的对象:
{
'apple': 'nice',
'banana': 'decent',
'cherry': 'yuck',
}
and I have these two methods: 我有两种方法:
function eatItems(cherry, apple) { }
function throwItem(banana) { }
My two questions: 我的两个问题:
Is it possible for me to invoke eatItem and send the arguments in the correct order? 我可以调用eatItem并以正确的顺序发送参数吗? Maybe something like:
也许像这样:
eatItems.call(this, {'cherry': cherry, 'apple': apple}); eatItems.call(this,{'cherry':cherry,'apple':apple});
What if I don't know what arguments eatItems receives, can I dynamically look up the names of the arguments for a function so I can know the order that I need to throw them in? 如果我不知道eatItems接收什么参数,该如何动态地查询一个函数的参数名称,以便知道将它们放入的顺序?
There's a way, indeed, and it involves calling toString
on a function: 确实有一种方法,它涉及到在函数上调用
toString
:
var source = eatItems.toString();
// => "function eatItems(cherry, apple) { }"
The next step is to parse the string you've got to get the names of the arguments: 下一步是解析要获取参数名称的字符串:
var args = source.substring(source.indexOf("(") + 1, source.indexOf(")")),
argNames = /\S/.test(args) ? args.split(/\s*,\s*/) : [];
A few caveats: 一些警告:
And, overall, this solution is more like an exercise. 总体而言,此解决方案更像是一种练习。 I wouldn't recommend taking this pattern in Javascript.
我不建议在Javascript中采用这种模式。 Don't forget that some functions handle a variable number of arguments, and you won't find them listed in their definition.
别忘了有些函数处理可变数量的参数,并且您不会在它们的定义中找到它们。 Rethink your code, and find a better way.
重新考虑您的代码,并找到更好的方法。
If I understand correctly you want extract the argument names from the function, and inject data from an object based on those names. 如果我理解正确,则需要从函数中提取参数名称,并基于这些名称从对象中注入数据。 This can be accomplished by converting the function to a string, extracting the arguments, and applying the function with those arguments:
这可以通过将函数转换为字符串,提取参数并使用带有这些参数的函数来实现:
function inject(data, f) {
var args = f.toString()
.match(/function\s*?\((.+?)\)/)
.pop()
.split(',')
.map(function(a){return data[a.trim()]})
return function() {
return f.apply(this, args)
}
}
var data = {
apple: 'nice',
banana: 'decent',
cherry: 'yuck',
}
var eat = inject(data, function(cherry, apple) {
console.log(cherry, apple)
})
eat() //=> yuck, nice
The obvious problem with this approach is that it is highly dependent on the variable names, so when you minify your code, the variables will get mangled and the function will stop working. 这种方法的明显问题是它高度依赖于变量名,因此,当您压缩代码时,变量将被弄乱,函数将停止工作。 This is a known problem in AngularJS, which uses something similar for their dependency injection.
这是AngularJS中的一个已知问题,它对依赖项注入使用了类似的方法。
This is often an XY problem, or an anti-pattern at the very least. 这通常是XY问题,或者至少是反图案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.