从JavaScript对象中调用具有正确参数的函数



假设我有一个对象,它看起来像这样:

{
     'apple': 'nice',
     'banana': 'decent',
     'cherry': 'yuck',
}

和我有这两个方法:

function eatItems(cherry, apple) { }
function throwItem(banana) { }

我的两个问题:

  1. 我是否可以调用eatiitem并以正确的顺序发送参数?比如:

    eatItems。调用(这一点,{樱桃:樱桃,"苹果":苹果});

  2. 如果我不知道eatItems接收到什么参数,我可以动态地查找函数的参数名称,这样我就可以知道我需要把它们扔进去的顺序吗?

确实有一种方法,它涉及到在函数上调用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*/) : [];

注意事项:

  1. 这个解决方案非常简单。它不处理函数定义中的注释。
  2. 并不是每个浏览器都可以正确地将函数转换为字符串(我想到了PS3浏览器),但它们确实是少数。
  3. 我还没有测试过,但在较慢的机器和/或功能较大的旧浏览器上可能存在一些性能问题。

总的来说,这个解决方案更像是一个练习。我不建议在Javascript中采用这种模式。不要忘记,有些函数处理的参数数量是可变的,您不会在它们的定义中找到它们。

如果我理解正确的话,您希望从函数中提取参数名称,并根据这些名称从对象中注入数据。这可以通过将函数转换为字符串、提取参数并使用这些参数应用函数来实现:

function inject(data, f) {
  var args = f.toString()
    .match(/functions*?((.+?))/)
    .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问题,或者至少是一个反模式。

相关内容

  • 没有找到相关文章

最新更新