很抱歉,如果我遗漏了一些明显的东西,但我无法弄清楚如何在javascript中绑定函数的特定(第n个)参数。我学到的大部分函数式编程都来自Scala,所以我不确定这在JS中是否可行。
例如,我知道我可以执行以下操作来绑定第一个参数
var add = function (a, b) {
return a + b;
};
add(1, 3); //returns 4
var addThree = add.bind(null, 3); //this = null. a = 3
addThree(4); //returns 7
但是如何绑定第二个参数并保留第一个参数。换句话说,我怎么才能绑定到'b'?
从mozilla - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind可以看出,参数实际上是嵌套的,看起来它必须按特定的顺序排列? (我很可能读错了)
编辑: 我意识到这是一个人为的例子。我只是想学习以防万一我最终处理比添加2个数字更复杂的事情。我也试图理解bind()参数实际上是如何工作的。
答案 0 :(得分:31)
当然你可以做到。这是使用扩展运算符(...
)的ES6解决方案,因为它更紧凑。
// Bind arguments starting after however many are passed in.
function bind_trailing_args(fn, ...bound_args) {
return function(...args) {
return fn(...args, ...bound_args);
};
}
如果您希望指定绑定开始的位置:
// Bind arguments starting with argument number "n".
function bind_args_from_n(fn, n, ...bound_args) {
return function(...args) {
return fn(...args.slice(0, n-1), ...bound_args);
};
}
在ES5中,你必须捣乱构建参数列表。
// ES5 version: construct arguments lists yourself
function bind_trailing_args(fn) {
var bound_args = [].slice.call(arguments, 1);
return function() {
var args = [].concat.call(arguments, bound_args);
return fn.apply(this, args);
};
}
与前两个示例不同,此示例正确处理this
。
在您的示例中:
var addThree = bind_trailing_args(add, 3);
addThree(1) // calls add(1, 3)
您还可以考虑使用JS可用的函数编程库之一,例如http://osteele.com/sources/javascript/functional/。你想要的东西在那里被称为rcurry
。
答案 1 :(得分:30)
您可以使用lodash' _.bind
来实现此目的:
var add = function(a, b) {
document.write(a + b);
};
// Bind to first parameter (Nothing special here)
var bound = _.bind(add, null, 3);
bound(4);
// → 7
// Bind to second parameter by skipping the first one with "_"
var bound = _.bind(add, null, _, 4);
bound(3);
// → 7

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.9.3/lodash.min.js"></script>
&#13;
我通常反对库并且更喜欢编写我自己的实用程序函数,但是很容易为lodash做一个例外。我强烈建议你每当有#34时检查its documentation;这必须是某处的语言!&#34;时刻。它在JavaScript中填补了很多空白。
答案 2 :(得分:9)
好。我把它扔到那里。
var add = function(a,b) {
return a + b;
};
var addThree = function(a) {
return add(a,3);
};
add(1,2);
addThree(4);
也许对某些人来说没问题。
答案 3 :(得分:0)
你可以试试这个:
Function.prototype.bindThemAll = function bindThemAll(thisArg, ...boundArgs)
(boundArgs.fn = this, function(...args) boundArgs.fn.call(thisArg || this, ...boundArgs.map((el) => el || args.shift()), ...args));
function fn() console.log("fn:", arguments.callee, "this:", this, "args:", arguments)
var x = {a: 5};
var bfn = fn.bindThemAll(x, null, 2)
bfn(1,3)
x.bfn = fn.bindThemAll(null, null, 2)
x.bfn(1,3)
带有null或undefined的绑定参数将按顺序替换为函数参数,其余参数将附加到结尾。 如果它被绑定将被使用,否则将使用当前的对象...
请参阅控制台了解结果!