在JavaScript中,我可以将参数绑定到类似的函数..
function foo(arg1, arg2) { console.log(arguments); }
foo = foo.bind(this, 'bar');
调用时,我们得到这个输出......
foo('baz');
> { '0': 'bar', '1': 'baz' }
是否可以跳过.bind()函数中的参数来实现以下输出?
function foo(arg1, arg2, arg3, arg4) { console.log(arguments); }
foo = foo.bind(this, 'bar', null, 'qux');
foo('baz', 'lel');
> { '0': 'bar', '1': 'baz', '2': 'lel', '3': 'qux' }
答案 0 :(得分:4)
看看Underscore的_.partial
:
通过填充任意数量的参数来部分应用函数,而不更改其动态此值。 您可以在参数列表中传递_以指定不应预先填充的参数,但在通话时保持打开状态。
在你的情况下:
function foo(arg1, arg2, arg3, arg4) { console.log(arguments); }
foo = _.partial(foo, 'bar', _, 'qux');
foo('baz', 'lel');
> { '0': 'bar', '1': 'baz', '3': 'qux', '4': 'lel'}
是的,我知道这不完全是你所说的。您似乎希望两个参数都被挤入_
所在的位置。除了明确指定在调用时将填充两个参数时,没有其他方法:
foo = _.partial(foo, 'bar', _, _, 'qux');
我不一定建议你使用它,但至少你可以看看他们的代码并获得一些提示。
如果您希望最终得到预定的参数,例如'qux'
,您将需要一些额外的机制。例如,这里有一个小例程(使用ES6,但你可以适应),它将一个函数转换为一个函数,其中指定的参数放在参数列表的末尾:
function partialEnd(fn, ...predefinedArgs) {
return function() {
return fn.apply(this, [...arguments, ...predefinedArgs]);
};
}
你可以这样使用:
function foo(a, b, c) { console.log(a + b + c); }
foo = partialEnd(foo, 3);
foo(1, 2) // outputs 6
您可以使用_.partial
占位符将其与_
结合使用,以获得将某些参数插入参数列表的效果,其他参数始终放在最后:
function foo(arg1, arg2, arg3, arg4) { console.log(arguments); }
foo = _.partial(foo, 'bar', _, _);
foo = partialEnd(foo, 'lel');
foo('baz', 'lel');
> { '0': 'bar', '1': 'baz', '3': 'lel', '4': 'qux'}
答案 1 :(得分:2)
JavaScript中不存在此类功能,但实现执行相同操作的功能相当简单:
function curryWithNulls(fn, thisObj) {
var curriedArgs = Array.prototype.slice.call(arguments, 2);
var length = curriedArgs.length;
return function() {
var args = Array.prototype.slice.call(arguments);
for (var i = 0; i < length || args.length; i++) {
if (i >= length || curriedArgs[i] === null) {
curriedArgs[i] = args.shift();
}
}
return fn.apply(thisObj, curriedArgs);
}
}
function foo(arg1, arg2, arg3, arg4) {
console.log(arguments);
}
var curriedFoo = curryWithNulls(foo, this, 'bar', null, null, 'qux');
curriedFoo('baz', 'lel');
// => { '0': 'bar', '1': 'baz', '2': 'lel', '3': 'qux' }
这与您的示例稍有不同,因为它需要为每个跳过的参数null
(而在您的示例中,您为两个参数填充了一个null
)。这允许在任何位置使用curried参数进行更复杂的构造,例如:
var curriedFoo2 = curryWithNulls(foo, this, null, 'bar', null, 'qux');
curriedFoo2('baz', 'lel');
// => { '0': 'baz', '1': 'bar', '2': 'lel', '3': 'qux' }
答案 2 :(得分:0)
不,你只是绑定null
。
函数的参数是函数的参数;绑定一个null
就是这样,它没有重新定义函数,它返回一个具有相同签名的新函数。
答案 3 :(得分:0)
可以使用功能组合:
var foo = function(arg1, arg2, arg3, arg4) { console.log(arguments); }
var bar = function(arg2, arg4) {
return foo.bind(this, 'bar', arg2, 'qux')();
}
bar('baz', 'lel');
或者,用现代语法:
const foo = (arg1, arg2, arg3, arg4) => console.log(arguments);
const bar = (arg2, arg4) => foo.bind(this, 'bar', arg2, 'qux')();
bar('baz', 'lel');
或根本没有绑定:
const foo = (arg1, arg2, arg3, arg4) => console.log(arguments);
const bar = (arg2, arg4) => foo(this, 'bar', arg2, 'qux', arg4);
bar('baz', 'lel');
P.S。不要忘记调用绑定的函数(在绑定后注意这些());