让我们说我的对象看起来像这样:
{
'apple': 'nice',
'banana': 'decent',
'cherry': 'yuck',
}
我有这两种方法:
function eatItems(cherry, apple) { }
function throwItem(banana) { }
我的两个问题:
我可以调用eatItem并以正确的顺序发送参数吗?也许是这样的:
eatItems.call(this,{' cherry&#39 ;: cherry,' apple&#39 ;: apple});
如果我不知道eatItems接收到什么参数,我可以动态查找函数参数的名称,这样我就可以知道我需要将它们放入的顺序吗?
答案 0 :(得分:2)
确实有一种方法,它涉及在函数上调用toString
:
var source = eatItems.toString();
// => "function eatItems(cherry, apple) { }"
下一步是解析您获取参数名称的字符串:
var args = source.substring(source.indexOf("(") + 1, source.indexOf(")")),
argNames = /\S/.test(args) ? args.split(/\s*,\s*/) : [];
一些警告:
总的来说,这个解决方案更像是一个练习。我不建议在Javascript中使用这种模式。不要忘记某些函数处理可变数量的参数,并且您不会在其定义中找到它们。重新思考你的代码,找到更好的方法。
答案 1 :(得分:1)
如果我理解正确,您需要从函数中提取参数名称,并根据这些名称从对象中注入数据。这可以通过将函数转换为字符串,提取参数,并使用这些参数应用函数来实现:
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
这种方法的一个明显问题是它高度依赖于变量名,因此当你缩小代码时,变量会被破坏,函数将停止工作。这是AngularJS中的一个已知问题,它使用类似的依赖注入。
这通常是XY问题,或者至少是反模式。