Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有人能帮我写并理解部分应用程序模式吗?_Javascript_Function_Functional Programming_Higher Order Functions_Partial Application - Fatal编程技术网

Javascript 有人能帮我写并理解部分应用程序模式吗?

Javascript 有人能帮我写并理解部分应用程序模式吗?,javascript,function,functional-programming,higher-order-functions,partial-application,Javascript,Function,Functional Programming,Higher Order Functions,Partial Application,我正在尝试使用回调函数编写一个函数,该函数将模拟以下行为: var fullName = function (firstName, lastName) { return firstName + ' ' + lastName; }; var michaelName = partial(fullName, 'Michael'); michaelName('Moore'); // 'Michael Moore' michaelName('Jackson'); // 'Michael Jackso

我正在尝试使用回调函数编写一个函数,该函数将模拟以下行为:

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

我在定义函数时写的是编写回调的一般模式吗?如果没有,有人能告诉我在哪里可以研究这个模式吗?是否有其他方法重构此回调以使其更干净?我不确定是否需要创建一个新的innerFunction,但当我创建时,我最终得到了预期的行为。我在代码注释中的推理是否准确?有人介意仔细阅读我的代码并进一步解释发生了什么,为什么从innerFunction返回回调,为什么partial返回innerFunction而不是回调?非常感谢。

如果您正在寻找更简洁的代码编写方法,我建议您使用Javascript闭包。这里有一个链接解释

如果你需要更好地理解回调,Youtube上有一些很棒的视频,这里有一篇帮助我理解的帖子

引自《邮报》的一段话

简单地说,回调函数就像一个调用 完成任务后,返回给他的经理


如果您正在寻找一种更简洁的代码编写方法,我建议您使用Javascript闭包。这里有一个链接解释

如果你需要更好地理解回调,Youtube上有一些很棒的视频,这里有一篇帮助我理解的帖子

引自《邮报》的一段话

简单地说,回调函数就像一个调用 完成任务后,返回给他的经理


据我理解,你的模式是正确的,尽管你的评论不太正确。下面是一个更通用的实现:

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));
    }
}
这与您的主要区别在于,它允许传入函数回调(在您的回调中)具有任意数量的参数,并且允许部分应用程序满足任意数量的参数……只要它们按顺序应用

请注意,建议不要以这种方式分割参数……同时还提供了这样做的示例。没有双重信息

好的,让我们来看看你的例子:

首先,声明基本函数-fullName。没有混乱。此函数有两个参数。部分应用程序的有用之处在于,您可能会发现自己现在知道一些参数,但在以后才知道其他参数。“部分应用程序”允许您立即应用一些参数,即“部分应用程序”,以获得与基函数具有相同效果的函数,但需要的参数较少,因为您已经提供了其他参数

接下来,调用var michaelName=partialfullname,Michael;这里你需要的是给我一个新的函数,叫做michaelName,如果第一个参数总是'Michael',而我只需要给它起个姓氏,那么fullName会做什么。一旦理解了这一点,代码的其余部分就开始有意义了

partial必须返回一个函数,而不是一个简单的值,因为这正是您所要求的——一个新的、更简单的回调版本。这个函数应该做什么?它应该给出如果用“Michael”和任何第二个函数调用回调函数的结果

下面是您的实现:

var partial = function(callback, firstName) {
    var innerFunction = function(lastName) { 
      return callback(firstName, lastName);
    };
    return innerFunction; 
}

这就是innerFunction。它是一个函数,将已知的firstName和新的lastName输入回调,然后返回结果。

据我所知,您的模式是正确的,尽管您的注释不太正确。下面是一个更通用的实现:

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));
    }
}
这与您的主要区别在于,它允许传入函数回调(在您的回调中)具有任意数量的参数,并且允许部分应用程序满足任意数量的参数……只要它们按顺序应用

请注意,建议不要以这种方式分割参数……同时还提供了这样做的示例。没有双重信息

好的,让我们来看看你的例子:

首先,声明基本函数-fullName。没有混乱。此函数有两个参数。部分应用程序的有用之处在于,您可能会发现自己现在知道一些参数,但在以后才知道其他参数。“部分应用程序”允许您立即应用一些参数,即“部分应用程序”,以获得与基函数具有相同效果的函数,但需要的参数较少,因为您已经提供了其他参数

接下来,调用var michaelName=partialfullname,Michael;你在这里要什么 就是给我一个新的函数,叫做michaelName,如果第一个参数总是'Michael',我只需要给它起个姓氏,那么fullName会做什么。一旦理解了这一点,代码的其余部分就开始有意义了

partial必须返回一个函数,而不是一个简单的值,因为这正是您所要求的——一个新的、更简单的回调版本。这个函数应该做什么?它应该给出如果用“Michael”和任何第二个函数调用回调函数的结果

下面是您的实现:

var partial = function(callback, firstName) {
    var innerFunction = function(lastName) { 
      return callback(firstName, lastName);
    };
    return innerFunction; 
}
这就是innerFunction。它是一个函数,将已知的firstName和新的lastName输入回调,然后返回结果。

是的,您编写的部分函数完全正确

我在这里使用回调这个词可以避免混淆自己。这个词通常在不同的上下文中使用:例如,指在完成某件事情时调用的例程,或forEach为数组的每个元素调用的例程。在这里,您传递的只是一个底层函数,当调用返回函数时,它将与一个额外的指定参数一起被调用。您也可以直接返回函数,以便

var partial = function(fn, firstName) {
    return function(lastName) {
        return fn(firstName, lastName);
    };
}
是否有其他方法重构此回调以使其更干净

不是真的,除了上面提到的。然而,它可以更一般化,见下文

我不确定是否需要创建一个新的innerFunction,但当我创建时,我最终得到了预期的行为

根据定义,partial需要返回一个函数。这就是它的目的。因此,是的,您必须创建要返回的函数。您可以将它创建为一个单独的命名函数,然后返回它,就像您所做的那样,或者在return语句中创建它,如上所述

我在代码注释中的推理是否准确

不完全是:

为了创建变量lastName的闭包,我声明了一个内部函数

但事实上,这个函数正在结束firstName,外部作用域中的变量

闭包已完成,还是只有在完成后才创建?以firstName和lastName作为参数返回名为callback的函数参数

不同的人对闭包的确切含义有不同的看法。有人会说,仅仅使用外部作用域中的变量定义函数就构成了闭包。其他人会说它不是一个闭包,或者至少称它为闭包是没有意义的,除非像您正在做的那样,函数被导出并返回以供外部使用

有人介意仔细阅读我的代码并进一步解释发生了什么,为什么从innerFunction返回回调,为什么partial返回innerFunction而不是回调

未从innerFunction返回回调;调用它的结果是。这正是您需要它的工作方式:您希望partial返回的函数调用最初传入的函数。直接从partial返回回调不会完成任何事情;您将返回传入的函数

因此,总体流程是:

您有一些像fullName这样的函数,并且希望创建另一个已经填充了第一个参数的函数

定义函数partial,该函数接受要填充参数的函数,以及要填充的参数

partial会记住要调用的函数以及传递给它的要填充的参数。它返回一个您想要的函数

调用从partial返回的partial函数,该函数使用预填充的参数调用原始函数,并向该函数传递一个以上的参数。这个函数您的内部函数可以看到要调用回调函数的函数和要填充的参数,因为它关闭在它们上面,这是一个从外部作用域访问这些变量的闭包

但是,您的部分权限有点有限。首先,它只处理一个预填充的参数。你可能想处理更多。而且,它不知道如何将其传递给innerFunction。您可以通过执行以下操作来解决此类问题:

function partial(fn, ...prefilledArgs) {
    return function(...additionalArgs) {
        return fn.call(this, ...prefilledArgs, ...additionalArgs);
    };
}
在上面,我使用了新的ES6 spread parameters特性,因为它更易于读写。在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));
    };
}
在上面,我们通过使用slice删除arguments伪数组的第一个元素fn,记住预先填充的参数并将其分配给变量prefilledArgs。然后,在内部函数中,我们连接预填充的参数和附加参数,并使用apply将整个列表传递给原始函数,这是在数组中包含参数时调用函数的方法。

是的,您编写的部分函数完全正确

我会避免受骗 在这里使用术语回调来融合你自己。这个词通常在不同的上下文中使用:例如,指在完成某件事情时调用的例程,或forEach为数组的每个元素调用的例程。在这里,您传递的只是一个底层函数,当调用返回函数时,它将与一个额外的指定参数一起被调用。您也可以直接返回函数,以便

var partial = function(fn, firstName) {
    return function(lastName) {
        return fn(firstName, lastName);
    };
}
是否有其他方法重构此回调以使其更干净

不是真的,除了上面提到的。然而,它可以更一般化,见下文

我不确定是否需要创建一个新的innerFunction,但当我创建时,我最终得到了预期的行为

根据定义,partial需要返回一个函数。这就是它的目的。因此,是的,您必须创建要返回的函数。您可以将它创建为一个单独的命名函数,然后返回它,就像您所做的那样,或者在return语句中创建它,如上所述

我在代码注释中的推理是否准确

不完全是:

为了创建变量lastName的闭包,我声明了一个内部函数

但事实上,这个函数正在结束firstName,外部作用域中的变量

闭包已完成,还是只有在完成后才创建?以firstName和lastName作为参数返回名为callback的函数参数

不同的人对闭包的确切含义有不同的看法。有人会说,仅仅使用外部作用域中的变量定义函数就构成了闭包。其他人会说它不是一个闭包,或者至少称它为闭包是没有意义的,除非像您正在做的那样,函数被导出并返回以供外部使用

有人介意仔细阅读我的代码并进一步解释发生了什么,为什么从innerFunction返回回调,为什么partial返回innerFunction而不是回调

未从innerFunction返回回调;调用它的结果是。这正是您需要它的工作方式:您希望partial返回的函数调用最初传入的函数。直接从partial返回回调不会完成任何事情;您将返回传入的函数

因此,总体流程是:

您有一些像fullName这样的函数,并且希望创建另一个已经填充了第一个参数的函数

定义函数partial,该函数接受要填充参数的函数,以及要填充的参数

partial会记住要调用的函数以及传递给它的要填充的参数。它返回一个您想要的函数

调用从partial返回的partial函数,该函数使用预填充的参数调用原始函数,并向该函数传递一个以上的参数。这个函数您的内部函数可以看到要调用回调函数的函数和要填充的参数,因为它关闭在它们上面,这是一个从外部作用域访问这些变量的闭包

但是,您的部分权限有点有限。首先,它只处理一个预填充的参数。你可能想处理更多。而且,它不知道如何将其传递给innerFunction。您可以通过执行以下操作来解决此类问题:

function partial(fn, ...prefilledArgs) {
    return function(...additionalArgs) {
        return fn.call(this, ...prefilledArgs, ...additionalArgs);
    };
}
在上面,我使用了新的ES6 spread parameters特性,因为它更易于读写。在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));
    };
}

在上面,我们通过使用slice删除arguments伪数组的第一个元素fn,记住预先填充的参数并将其分配给变量prefilledArgs。然后,在内部函数中,我们连接预填充的参数和附加参数,并使用apply将整个列表传递给原始函数,这是在数组中有参数时调用函数的方法。

您没有抓住要点。他试图将函数全名转换为部分函数。不仅仅是编写一个生成器。是的@slebetman,我不需要将partial作为生成器编写-我想在编写partial函数时使用fullName。我这样做对吗?好的,对不起,我现在明白了。这可能会帮到你,你没抓住重点。他试图将函数全名转换为部分函数。不仅仅是编写一个生成器。是的@slebetman,我不需要将partial作为生成器编写-我想在编写partial函数时使用fullName。我这样做对吗?好的,对不起,我现在明白了。这可能对你有所帮助。