JavaScript 部分应用函数 - 如何仅绑定第二个参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27699493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript partially applied function - How to bind only the 2nd parameter?
提问by Justin Maat
Sorry if I'm missing something obvious, but I can't figure out how to bind a specific (nth) argument of a function in javascript. Most of my functional programming I've learned has been from Scala so I'm not sure this is even possible in JS.
抱歉,如果我遗漏了一些明显的东西,但我无法弄清楚如何在 javascript 中绑定函数的特定(第 n 个)参数。我学到的大部分函数式编程都来自 Scala,所以我不确定这在 JS 中是否可行。
For example, I understand I can do the below to bind the 1st argument
例如,我知道我可以执行以下操作来绑定第一个参数
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
But how can I bind the 2nd argument and leave the first as is. In other words how can I bind to 'b' only?
但是我怎样才能绑定第二个参数并保持第一个不变。换句话说,我怎样才能只绑定到“b”?
From what i can tell from mozilla - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind, the arguments are actually nested which makes it look like it has to be in specific order? (I'm very possibly reading this wrong)
从我可以从 mozilla 了解到的 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind,参数实际上是嵌套的,这使它看起来必须是具体顺序?(我很可能读错了)
Edit: I realize this is a sort of contrived example. I'm just trying to learn in case I eventually deal with something more complex than adding 2 numbers. I'm also trying to understand how the bind() arguments are actually working under the hood.
编辑:我意识到这是一种人为的例子。我只是想学习,以防我最终处理比添加 2 个数字更复杂的事情。我还试图了解 bind() 参数实际上是如何在幕后工作的。
采纳答案by Justin Maat
Of course you can do it. Here's an ES6 solution using the spread operator (...
), since it's a bit more compact.
你当然可以做到。这是使用扩展运算符 ( ...
)的 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);
};
}
If you'd prefer to specify the position at which binding starts:
如果您希望指定绑定开始的位置:
// 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);
};
}
IN ES5, you have to muck around with constructing argument lists.
在 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);
};
}
Unlike the first two examples, this one handles this
properly.
与前两个示例不同,这个示例处理this
得当。
In the context of your example:
在您的示例的上下文中:
var addThree = bind_trailing_args(add, 3);
addThree(1) // calls add(1, 3)
You could also consider using one of the functional programming libraries available for JS, such as http://osteele.com/sources/javascript/functional/. The thing you want is called rcurry
there.
您还可以考虑使用可用于 JS 的函数式编程库之一,例如http://osteele.com/sources/javascript/functional/。你想要的东西在rcurry
那里被调用。
回答by AlicanC
You can use lodash's _.bind
to achieve this:
您可以使用 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>
I am usually against libraries and prefer coding my own utility functions, but an exception can easily be made for lodash. I would highly suggest you check its documentationwhenever you have a "This must be in the language somewhere!" moment. It fills in a lot of blanks in JavaScript.
我通常反对库,更喜欢编写自己的实用程序函数,但是 lodash 很容易例外。我强烈建议您在遇到“这必须是某处的语言!”时检查其文档。片刻。它填补了 JavaScript 中的很多空白。
回答by Benjamin
Well. I'll just throw this out there.
好。我会把这个扔在那里。
var add = function(a,b) {
return a + b;
};
var addThree = function(a) {
return add(a,3);
};
add(1,2);
addThree(4);
Maybe it will be ok for some.
也许对某些人来说没问题。
回答by yochaim
you can try this:
你可以试试这个:
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)
bound arguments with null or undefined will be replaced with the function arguments in order, the remaining arguments will be appended to the end. an object will be used if it is bound otherwise the current this will be used...
带有 null 或 undefined 的绑定参数将按顺序替换为函数参数,其余参数将附加到末尾。如果绑定了对象,则将使用该对象,否则将使用当前的 this...
see console for results!
结果见控制台!