传递带参数的函数作为参数并检索数据

时间:2015-08-06 16:02:36

标签: javascript function

大家早上好,

所以我有一个相当混乱的问题,所以我会尽量保持清晰,并保持简洁。

假设我有一个函数basicFunctionbasicFunctionfuncWithParamscallback两个参数。

basicFunction(funcWithParams, callback){
    .
    .
    .
    // do stuff here
}

funcwIthParams正是它所说的,带有或带有参数的函数,参数callback是一个在basicFunction的初始部分完成时触发的函数。

尽管如上所述,这是我的问题。是否可以在传递带参数的函数时获取函数名本身,以及随之传递的每个参数以及每个传递参数的值?我知道你肯定可以将函数名称作为字符串,但我不完全确定每个参数和值。

过去三天我一直在疯狂地研究这个问题,我确信有办法,但我还没有找到答案。

示例

function basicFunction(funcWithParams, callback){
     // create a loop to go through and log each of the parameters in the first argument's function

}

function somethingElse(param1, param2, param3){

}

function callbackFunction(){
   alert("I did stuff");
}

basicFunction(somethingElse(param1, param2, param3), callbackFunction);

2 个答案:

答案 0 :(得分:1)

我认为你可能正在寻找通常被称为部分应用 currying 的东西(在数学家Haskell Curry之后)。

JavaScript没有纯粹的currying(内置;它很容易添加),但有Function#bind,它允许你创建一个基于另一个函数的函数,当被调用时,将调用原始函数一个特定的this值以及您提供的任何参数。如果您不关心this,请使用null。正如泥浆那样清楚,让我们举个例子:

function foo(a, b) {
  snippet.log(a + ", " + b);
}
foo(1, 2); // "1, 2"

// Create curried version
var bar = foo.bind(null, 100);

// Call curried version
bar(200);  // "100, 200"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

在那里,当我从a创建bar时,我们“讨论”了参数foo的值100。

所以在你的例子中,你会这样做:

basicFunction(somethingElse.bind(null, param1, param2, param3), callbackFunction);

重新评论:

  

这几乎就是我要做的事情,但我正在看的是像bar(foo(1,2), 100);这样的东西,从而将“foo”的结果作为字符串,值为1和2.

如果您执行bar(foo(1,2),100)foo使用参数12获取名为的,然后将其返回值传递给{ {1}}以及bar。在调用100时,没有任何信息传递给它,以任何方式引用barfoo1。正好2设置x = foo(1, 2) foo的返回值的方式,再次没有任何内容继续引用回x(或foo或{{1}来自1

如果你想访问args,那么唯一想到的就是传递一个带有函数及其参数的对象,如下所示:

2

然后,在x

bar({f: foo, args: [1, 2]}, 100);

bar调用你调用它的函数,使用你给它的第一个参数作为调用的function bar(finfo, additionalArg) { console.log(finfo.f.name); // "foo", probably, see caveats console.log(finfo.args[0]); // 1 console.log(finfo.args[1]); // 2 // calling it finfo.f.apply(null, finfo.args); } 值,然后使用你给它作为数组的参数作为单个参数通过该功能。

直播示例

Function#apply
this

注意事项:

  1. function foo(a, b) { snippet.log("foo called with " + a + " and " + b); } function bar(finfo, additionalArg) { console.log(finfo.f.name); // "foo", probably, see caveats console.log(finfo.args[0]); // 1 console.log(finfo.args[1]); // 2 // calling it snippet.log("bar calling finfo.f via apply"); finfo.f.apply(null, finfo.args); } snippet.log("Calling bar"); bar({f: foo, args: [1, 2]}, 100);通常由浏览器提供,但直到今年6月ECMAScript第6版(ES6)问世时才成为规范的一部分。所以你可能会发现不支持它的奇怪浏览器。如果是这样,你可能不得不做可怕的<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>事情来弄清楚函数的名称。

  2. 并非所有函数都有名称。 ES6提供了许多以前匿名的函数名称,但仍然可以创建匿名函数,并且并非所有浏览器都支持ES6推断函数名称的各种方式(例如,来自Function#name等表达式。)

    < / LI>

    toString提供名称的唯一真正保证方式是在创建函数时手动执行此操作:

    var f = function() { };

    很快就会出现这种情况,但这是在今天的世界。

答案 1 :(得分:0)

如果您正在使用类的实例,则可能需要担心上下文。在这种情况下,绑定是有意义的。例如:

function Sum() {
  this._total = 0;
  this.addTen = this.add.bind(this, 10);
}

Sum.prototype.add = function(amount) {
  this._total += amount;
  return this;
};

Sum.prototype.toString = function() {
  return '' + this._total;
};

var sum = new Sum();
sum.addTen().addTen();
console.info(sum);
// 20

但是,在实例之外,通常不需要上下文,更合适的currying形式可能是创建工厂函数,如下所示:

function createAdder(amount1) {
  return function AddTo(amount2) {
    return amount1 + amount2;
  };
}

var addTenTo = createAdder(10);
var fifty = addTenTo(40);

console.info(fifty);
// 50

这通常归结为实施细节和偏好。这两种方法都有很好的用途和论据。