大家早上好,
所以我有一个相当混乱的问题,所以我会尽量保持清晰,并保持简洁。
假设我有一个函数basicFunction
。 basicFunction
有funcWithParams
和callback
两个参数。
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);
答案 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
使用参数1
和2
获取名为的,然后将其返回值传递给{ {1}}以及bar
。在调用100
时,没有任何信息传递给它,以任何方式引用bar
,foo
或1
。正好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
注意事项:
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>
事情来弄清楚函数的名称。
并非所有函数都有名称。 ES6提供了许多以前匿名的函数名称,但仍然可以创建匿名函数,并且并非所有浏览器都支持ES6推断函数名称的各种方式(例如,来自Function#name
等表达式。)
为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
这通常归结为实施细节和偏好。这两种方法都有很好的用途和论据。