我试图编写一个利用回调来模仿此行为的函数:
var fullName = function (firstName, lastName) {
return firstName + ' ' + lastName;
};
var michaelName = partial(fullName, 'Michael');
michaelName('Moore'); // 'Michael Moore'
michaelName('Jackson'); // 'Michael Jackson'
我被困了一段时间,试图编写一个名为
partial
的函数,该函数将回调该函数fullName
,但最终使它起作用,但不确定它是(a)正确的,还是(b)到底在发生什么。var partial = function(callback, firstName) {
var innerFunction = function(lastName) { //I declared an inner function in order to create a closure of the variable lastName
return callback(firstName, lastName); //The closure is completed (or is it only then created?) by returning the function argument named callback taking firstName and lastName as arguments
};
return innerFunction; //the function partial will finally return the closure, function innerFunction
}
var michaelName = partial(fullName, 'Michael');
console.log(michaelName('Moore')); //Michael Moore
我在定义函数
partial
中编写的内容是编写回调的一般模式吗?如果没有,有人可以显示/指出我在哪里可以学习这种模式?还有其他方法可以重构此回调以使其更干净吗?我不确定是否需要创建一个新的innerFunction
,但是当我这样做时,我终于使行为按预期工作了。我在代码注释中的推理是否正确?有人会介意逐步检查我的代码并进一步解释正在发生的事情吗,为什么从callback
返回innerFunction
以及为什么partial
返回innerFunction
而不是callback
?非常感谢。
最佳答案
是的,您已编写partial
功能完全正确。
我会避免在此处使用“回调”一词来混淆自己。该词通常在不同的上下文中使用:表示完成某事后调用的例程,或者例如由forEach
为数组的每个元素调用的例程。在这里,您传递的只是一个基础函数,当调用返回的函数时,该函数将与一个额外的指定参数一起被调用。您也可以直接返回该函数
var partial = function(fn, firstName) {
return function(lastName) {
return fn(firstName, lastName);
};
}
还有其他方法可以重构此回调以使其更干净吗?
除了上面提到的以外,不是真的。但是,可以使其更通用(请参见下文)。
我不确定是否需要创建一个新的
innerFunction
,但是当我这样做时,我终于使行为按预期工作了。根据定义,
partial
需要返回一个函数。这就是它的目的。是的,您必须创建要返回的函数。您可以将其创建为单独的命名函数,然后像您一样将其返回,或者直接在return语句中创建它,如上所述。我在代码注释中的推理是否正确?
不是完全:
我声明了一个内部函数以创建变量
lastName
的闭包但是实际上,此函数正在关闭
firstName
(外部作用域中的变量)。通过返回以firstName和lastName作为参数的名为callback的函数参数来完成关闭(或仅是随后创建?)
关于封闭的确切含义,不同的人有不同的想法。有人会说,仅使用外部作用域中的变量定义函数就构成了闭包。其他人会说它不是一个闭包,或者至少称它为闭包是没有意义的,除非像您所做的那样,从外部使用“导出”(返回)该函数以供使用。
有人会介意逐步检查我的代码并进一步解释正在发生的事情吗,为什么从
callback
返回innerFunction
以及为什么partial
返回innerFunction
而不是callback
?callback
不是从innerFunction
返回的;调用它的结果是。这正是您需要它的工作方式:您希望partial
返回的函数调用您最初传入的函数。直接从callback
返回partial
不会完成任何操作;而是直接从fullName
返回。您将只返回您传入的函数。因此,总体流程为:
您有一些像
partial
这样的函数,并且您想要创建另一个函数,该函数的第一个参数为“已经填充”。定义函数
partial
,该函数需要一个函数来填充其参数,并填充参数。partial
“记住”要调用的函数,并将要填写的参数传递给它。它返回一个函数(这就是您想要的)您调用从
innerFunction
返回的部分函数,该函数使用预填充的参数调用原始函数,然后再将另一个函数传递给该函数。该函数(您的callback
)可以“看到”要调用的函数(您称为this
)和要填充的参数,因为它关闭了它们(这是从外部范围访问那些变量的闭包。但是,您的偏颇有些局限。一方面,它仅处理一个预填充的参数。您可能想处理更多。另外,它也不知道如何通过
innerFunction
传递到prefilledArgs
。您可以通过以下方法解决此类问题:function partial(fn, ...prefilledArgs) {
return function(...additionalArgs) {
return fn.call(this, ...prefilledArgs, ...additionalArgs);
};
}
在上面,我使用了新的ES6“扩展参数”功能,因为它更易于读写。在ES5中,您需要使用数组函数将预先填充的参数和其他参数拼接在一起,这并不太有趣,如下所示:
function partial(fn)
var prefilledArgs = Array.prototype.slice.call(arguments, 1);
return function() {
var additionalArgs = Array.prototype.slice.call(arguments);
return fn.apply(this, prefilledArgs.concat(additionalArgs));
};
}
在上面的代码中,通过使用
fn
删除参数伪数组的第一个元素(slice
),我们“记住”了预填充的参数并将它们分配给变量apply
。然后,在内部函数内部,我们连接预填充的参数和其他参数,然后使用关于javascript - 有人可以帮我编写和理解部分应用程序模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29788813/