我试图使用会模仿此行为的回调来编写函数:
var fullName = function (firstName, lastName) {
return firstName + ' ' + lastName;
};
var michaelName = partial(fullName, 'Michael');
michaelName('Moore'); // 'Michael Moore'
michaelName('Jackson'); // 'Michael Jackson'
我被困了一段时间试图编写一个名为partial
的函数,该函数将回调函数fullName
,但最终让它工作但不确定它是否正确#) 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
?很有责任。
答案 0 :(得分:3)
是的,您已经写过partial
功能完全正确。
我会通过使用术语"回调"来避免让自己感到困惑。这里。该单词通常用于不同的上下文中:表示在完成某事时调用的例程,或者例如由forEach
为数组的每个元素调用的例程。在这里,你传入的只是一个底层函数,当调用返回的函数时,它将与一个额外的指定参数一起调用。您也可以直接返回该功能,只需
var partial = function(fn, firstName) {
return function(lastName) {
return fn(firstName, lastName);
};
}
有没有其他方法可以重构此回调以使其更清晰?
不是真的,除了上面提到的。但是,它可以更加通用(见下文)。
我不确定是否需要创建新的
innerFunction
,但是当我这样做时,我终于让行为按预期工作。
根据定义,partial
需要返回一个函数。这就是它的目的。所以是的,你必须创建你要返回的功能。您可以将其创建为单独的命名函数,然后像往常一样将其返回,或者在return语句中创建它,如上所述。
我对代码的评论中的推理是否准确?
不完全:
我声明了一个内部函数,以便创建变量
的闭包lastName
但实际上这个函数正在关闭firstName
,这是来自外部范围的变量。
通过返回名为callback的函数参数将firstName和lastName作为参数
来完成闭包(或者只是创建它?)
不同的人对关闭的确切含义有不同的看法。有人会说仅仅使用外部范围的变量定义函数就构成了一个闭包。其他人会说它不是一个闭包,或者至少将它称为闭包是没有意义的,除非该功能是"导出" (返回)从外面使用,就像你一样。
有人会介意踩过我的代码并进一步解释发生了什么,为什么
callback
从innerFunction
返回,为什么partial
会返回innerFunction
而不是callback
}?
callback
未从innerFunction
返回;它的结果是调用。这正是您需要它的工作方式:您希望partial
返回的函数调用您最初传入的函数。直接从callback
返回partial
将无法完成任何操作;你只需要返回传入的函数。
所以整体流程是:
你有一些像fullName
这样的函数,你想要创建另一个函数,其中第一个参数"已填入"。
定义函数partial
,它接受一个函数来填充参数,以及要填充的参数。
partial
"记得"要调用的函数和传入的参数传递给它。它返回一个函数(这是你想要的)
您调用从partial
返回的部分函数,该函数使用预填充参数调用原始函数,并将另一个函数传递给该函数。该功能(您的innerFunction
)可以"看到"要调用的函数(你称之为callback
)和要填充的参数,因为关闭它们(它是从外部范围访问这些变量的闭包。
但是,你的偏见有点受限。首先,它只处理一个预先填充的参数。您可能想要处理更多。此外,它还不知道如何通过this
传递给innerFunction
。您可以通过以下方式解决这些问题:
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));
};
}
在上面,我们记得"通过使用prefilledArgs
删除参数伪数组的第一个元素(fn
),将预填充的参数分配给变量slice
。然后,在内部函数内部,我们连接预先填充的参数和附加参数,并使用apply
将整个列表传递给原始函数,这是在有参数时调用函数的方法。阵列。
答案 1 :(得分:1)
如果您正在寻找一种更清晰的方式来编写代码,我建议您使用Javascript闭包。这是一个解释closures的链接。
var partial = function( firstName) {
return function(lastName) {
return firstName + " " + lastName
};
}
var michaelName = partial('Michael');
console.log(michaelName('Moore'));
如果你需要更好地理解回调,Youtube有一些很棒的视频,这里有一个帮助我理解Callbacks的叠加帖子。
帖子的引用
简单来说,回调函数就像是“调用”的工人 当他完成任务时回到他的经理。
答案 2 :(得分:1)
虽然您的评论不是很正确,但您已经了解了我所理解的模式。这是一个更通用的实现:
var partial = function(fn) {
var appliedArgs = Array.prototype.slice.call(arguments,1);
return function() {
var moreArgs = Array.prototype.slice.call(arguments);
return fn.apply(this,appliedArgs.concat(moreArgs));
}
}
这与你的主要区别在于它允许传入的函数(callback
,在你的)中有任意数量的参数,并允许部分应用程序满足任意数量的那些...只要它们按顺序应用。
(请注意,MDN docs建议不要那样切片arguments
......同时也提供了这样做的示例。那里没有双重消息!)
好的,让我们逐步介绍你的例子:
首先,您声明基本函数 - fullName()
。那里没有混乱。这个函数有两个参数。部分应用程序的有用之处在于,您可能会发现自己处于一个您现在知道某些参数的位置,但直到稍后才知道其他参数。部分应用程序允许您立即应用一些参数(因此部分应用程序'),获取与基本功能具有相同效果的函数,但需要更少的参数(因为您已经提供其他人。)
接下来,您拨打电话var michaelName = partial(fullname,"Michael");
您在这里要求的是"给我一个名为michaelName
的新功能,它可以执行fullName
如果第一个参数始终是' Michael'我只需要给它起一个姓氏"。一旦你理解了这一点,其余的代码就开始变得有意义了。
partial()
必须返回一个函数,而不是一个简单的值,因为这是你要求的 - 一个新的,更简单的你传入的回调版本。那应该是什么功能呢?如果用“迈克尔”调用它,它应该给出回调结果。以及它给出的第二个功能。
再次执行您的实施:
var partial = function(callback, firstName) {
var innerFunction = function(lastName) {
return callback(firstName, lastName);
};
return innerFunction;
}
这正是innerFunction()
的确切含义。它是一个功能,可将已知的firstName
和新的lastName
提供给callback()
,然后返回结果。