Javascript 返回函数的函数不会抛出错误,尽管参数未定义

Javascript 返回函数的函数不会抛出错误,尽管参数未定义,javascript,redux,higher-order-functions,Javascript,Redux,Higher Order Functions,我在一个教程中看到了以下代码片段: const myFunction = () => { return function (caller) { caller(firstFuctnion()); caller(secondFunction()); }; }; 一旦我这样称呼它,你能告诉我它是如何工作的吗 myFunction() 当调用方参数实际上没有定义时,为什么我没有得到错误 另一方面,如果我省略它,然后像这样编写代码: const myFunctio

我在一个教程中看到了以下代码片段:

const myFunction = () => {
   return function (caller) {
     caller(firstFuctnion());
     caller(secondFunction());
   };
};
一旦我这样称呼它,你能告诉我它是如何工作的吗

myFunction()
当调用方参数实际上没有定义时,为什么我没有得到错误

另一方面,如果我省略它,然后像这样编写代码:

const myFunction = () => {
   return function () {
     firstFuctnion();
     secondFunction();
   };
 };
这两个函数FirstFunction和secondFunction不执行。那么,打电话的人到底是怎么说的 — 或者不管它叫什么 — 工作

对于那些可能希望看到整个功能代码的人:

const redux=requireredux; const thunk middleware=requireredux-thunk.default; const axios=要求性; const createStore=redux.createStore; 常量applyMiddleware=redux.applyMiddleware; 常量初始状态={ 加载:false, 用户:[], 错误:, }; const FETCH\u USERS\u REQUEST=FETCH\u USERS\u REQUEST; const FETCH\u USERS\u SUCCESS=FETCH\u USERS\u SUCCESS; const FETCH\u USERS\u FAILURE=FETCH\u USERS\u FAILURE; const fetchUsersRequest==>{ 返回{ 类型:获取用户请求, }; }; const fetchUsersAccess=用户=>{ 返回{ 类型:获取用户成功, 有效载荷:用户, }; }; const fetchUsersFailure=错误=>{ 返回{ 类型:获取用户失败, 有效载荷:错误, }; }; const fetchUsers==>{ 返回函数调度{ dispatchfetchUsersRequest; axios .gethttps://jsonplaceholder.typicode.com/users .thenresponse=>{ //response.data就是用户 const users=response.data.mapuser=>user.id; DispatchFetchUsersAccessUsers; } .catcherror=>{ //error.message是错误消息 dispatchfetchUsersFailureerror.message; }; }; }; const reducer=state=initialState,action=>{ console.logaction.type; 开关动作类型{ 案例获取用户请求: 返回{ 状态 加载:对, }; 案例获取\用户\成功: 返回{ 加载:false, 用户:action.payload, 错误:, }; 案例获取\用户\失败: 返回{ 加载:false, 用户:[], 错误:action.payload, }; } }; const store=createStorereducer,applyMiddlewarethunkMiddleware; store.subscribe=>{ console.logstore.getState; };
store.dispatchfetchUsers 我想你还没有把整只鹬都印出来。因为在myFunction中没有firstFunction和secondFunction的定义

要回答您的问题,如果要调用myFunction中定义的函数,需要在新变量返回函数时将该值赋给它。然后进行简单的函数调用

const myFunctionResult = myFunction();
myFunctionResult(someOtherCallerFunction);


但是请注意,由于上述原因,这将抛出一个错误。

我认为您还没有打印整个snipet。因为在myFunction中没有firstFunction和secondFunction的定义

要回答您的问题,如果要调用myFunction中定义的函数,需要在新变量返回函数时将该值赋给它。然后进行简单的函数调用

const myFunctionResult = myFunction();
myFunctionResult(someOtherCallerFunction);


但请注意,由于上述原因,这将引发错误。

函数与任何其他值一样处理,这意味着它们可以从函数返回。 调用myFunction将只返回内部函数,这将要求在调用myFunction时向其传递参数调用方

内部函数将记住传递给其封闭函数的任何参数

我用来理解这个概念的一个例子是乘数工厂函数

常数回答=函数{ 答案是:; } 常数乘数=函数因子{ 返回函数{ 答复 console.log n*系数; }; } 常数两次=乘法器2; 常数三=乘法器3; twice4;//答案是:8
三倍5;//答案是:15函数与任何其他值一样处理,这意味着它们可以从函数返回。 调用myFunction将只返回内部函数,这将要求在调用myFunction时向其传递参数调用方

内部函数将记住传递给其封闭函数的任何参数

我用来理解这个概念的一个例子是乘数工厂函数

常数回答=函数{ 答案是:; } 常数乘数=函数因子{ 返回函数{ 答复 console.log n*系数; }; } 常数两次=乘法器2; 常数三=乘法器3; twice4;//答案是:8
三倍5;//答案是:15

让我们考虑这个代码的简化版本。 在你为你的问题添加一些重要的上下文之前——myFunction实际上正在被使用,以及它是如何被使用的——我不太确定你的困惑在哪里,所以这个答案从回调、高阶函数和咖喱的一般解释开始

首先,让我们打开函数 变成了一个箭头函数,所以代码读起来更直截了当。 他们之间有一些分歧,但现在让我们忽略它们。 让我们把myFunction重命名为outer,这样我们就知道我们在谈论哪个函数了

常量外部==>{ 返回调用者=>{ 呼叫者某物; }; }; 外部是一个函数。 外部也是一种功能;也就是说,函数outer的返回值本身就是一个函数

由于outer是a,因此根据HOFs1的两个定义之一,这使得outer成为a

为了明确起见,您可以使用另一个变量引用返回的函数:

常数内部=外部; 当调用方参数实际上没有定义时,为什么我没有得到错误

这是一个奇怪的问题;当调用outer时,它还未触及调用方。 只有调用内部函数才可以

扪心自问:为什么这里没有定义a和b的错误

常数和=a,b=>a+b; 总和 是的:sum甚至都不叫! 就像外线连名字都不叫

即使再进一步,这也不会抛出错误,即使somethingUndefined没有在任何地方定义,也不能在任何地方设置。 但是你会得到警告

const someFunction==>somethingUndefined; 某些功能; 在这个常见的HOFs示例中,尽管在add5分配给add5的点上没有定义b,但为什么这里没有出现错误

const add=a=>{ 返回b=>a+b; }; //或者更简单地说: //常量add=a=>b=>a+b; 常数addFive=add5; console.logaddFive3;//品脱8。 因为还没有调用需要b的函数,即addFive

如果由于未定义调用方而要强制执行错误,则必须调用实际需要定义调用方的函数。所讨论的功能是外部的!像任何其他函数一样,用:outer调用它。现在您得到一个TypeError,因为调用者不是函数

这种“双重呼叫”被称为

代码也可以这样重写。 唯一的区别是内部现在也可以在外部作用域中访问,而外部作用域是。 看

常量内部=调用方=>{ 呼叫者某物; }; 常量外部==>内部; inner充当返回函数outer的角色。 它将函数作为参数,并使用某个对象作为参数调用它

outer只是一个返回函数inner的函数,其他什么都不返回。 它不呼叫它,它不接触呼叫者,它与某事无关

外部和内部是相同的

另一方面,如果我省略它并编写代码[没有调用者],这两个函数FirstFunction和secondFunction将不会执行。那么,打电话的人到底是怎么说的 — 或者不管它叫什么 — 工作

首先,让我们修复语义:FirstFunction和secondFunction是函数调用。 它们是否是函数,取决于FirstFunction和secondFunction返回什么。 FirstFunction和secondFunction是函数,至少代码表明它们是函数

更具体地,考虑警戒:

警报是一种功能;你可以把它叫做警报。 警报不是一种功能;你不能像警报一样叫它。 调用者是一个回调函数。 如果您在代码中省略了caller,那么myFunction将是正确的调用,它不会抛出错误,只调用firstFuction和secondFunction

但是回调的目的是将FirstFunction和secondFunction的结果传递给函数调用方。 您必须自己提供该功能,例如警报功能

myFunctionalert调用内部函数,向其传递警报。 内部函数调用FirstFunction和secondFunction,并将其结果传递给调用者,我们将其指定为警报

一旦我像调用myFunction一样调用它,你能告诉我它是如何工作的吗

很简单,这里什么也没发生。 myFunction返回一个函数,就这样;该函数没有被进一步使用,因此被丢弃

高阶函数有一个关键方面没有在本代码中演示:封装值。 考虑这个代码:

const add=a=>{ 让计数=0; 返回b=>{ ++计数; log`将${a}添加到其他对象的函数已被调用${count}次。`; 返回a+b }; }; add和b的工作方式与以前的myFunction和caller类似,但现在,外部函数也需要一个参数,因此add没有帮助。 add5调用add函数并将参数a设置为5。 此外,add53调用内部返回函数,将b设置为3并返回8

但是在add中还有一些状态,它是一个名为count的变量

常数addFive=add5; console.logaddFive3;//印刷品8。 //但也记录:向其他内容添加5的函数已被调用1次。 console.logaddFive10;//打印15张。 //但也记录:向其他内容添加5的函数已被调用2次。 计数仅可在外部includ内部访问 对其内部的任何功能进行加密;它是“封装的”。 这是隐藏某些状态的常用方法,这些状态应该只能在特定函数中访问

a实际上也封装在add…;a和count具有相同的作用域,彼此之间没有太大区别,只是在调用add时可以将a设置为参数,而count不能

然后,您添加了更多上下文,其中调用看起来更像这样:

const myFunction = () => {
   return function () {
     firstFuctnion();
     secondFunction();
   };
 };
其他函数我的函数 这与之前的情况不同,之前您只编写了类似myFunction的调用。 现在,结果不会被丢弃,因为它被输入到原始代码中的其他函数中:store.dispatch

[caller]没有作为参数传递,也没有在任何地方定义

但是现在,另一个函数的任务是使用适当的回调函数作为参数调用myFunction。 现在,您不需要自己传递函数;取而代之的是,其他函数为您执行此操作

将此与。 如果返回前面的sum示例函数,则可以自己传递参数:

sum1,2; 或者某个库或框架为您提供:

//库代码 const dotherlightthing=callback=>callback1,2; //你的代码 多瑟莱特森; 或内置或主机定义的函数为您执行以下操作:

[1,2,3]。还原度为0; 这些参数来自何处或函数从何处调用都无关紧要。 但是它被调用了,并且在某个地方用正确的参数调用了它

1:高阶函数的两个定义是

返回函数的函数,或 将另一个函数作为参数的函数。 外层符合第一个定义。 外部独立且巧合地符合第二个定义


2:好吧,当然,sum也不会抛出错误,但是a和b都是未定义的。undefined+undefined具有不会导致错误的语义,但希望您能理解这一点:在原始代码中,myFunction会抛出错误,只是因为undefinedfirstFunction不可能。罪魁祸首是相同的:调用方是未定义的。

让我们考虑这个代码的简化版本。 在你为你的问题添加一些重要的上下文之前——myFunction实际上正在被使用,以及它是如何被使用的——我不太确定你的困惑在哪里,所以这个答案从回调、高阶函数和咖喱的一般解释开始

首先,让我们将函数转换为箭头函数,这样代码更易于阅读。 他们之间有一些分歧,但现在让我们忽略它们。 让我们把myFunction重命名为outer,这样我们就知道我们在谈论哪个函数了

常量外部==>{ 返回调用者=>{ 呼叫者某物; }; }; 外部是一个函数。 外部也是一种功能;也就是说,函数outer的返回值本身就是一个函数

由于outer是a,因此根据HOFs1的两个定义之一,这使得outer成为a

为了明确起见,您可以使用另一个变量引用返回的函数:

常数内部=外部; 当调用方参数实际上没有定义时,为什么我没有得到错误

这是一个奇怪的问题;当调用outer时,它还未触及调用方。 只有调用内部函数才可以

扪心自问:为什么这里没有定义a和b的错误

常数和=a,b=>a+b; 总和 是的:sum甚至都不叫! 就像外线连名字都不叫

即使再进一步,这也不会抛出错误,即使somethingUndefined没有在任何地方定义,也不能在任何地方设置。 但是你会得到警告

const someFunction==>somethingUndefined; 某些功能; 在这个常见的HOFs示例中,尽管在add5分配给add5的点上没有定义b,但为什么这里没有出现错误

const add=a=>{ 返回b=>a+b; }; //或者更简单地说: //常量add=a=>b=>a+b; 常数addFive=add5; console.logaddFive3;//品脱8。 因为还没有调用需要b的函数,即addFive

如果由于未定义调用方而要强制执行错误,则必须调用实际需要定义调用方的函数。所讨论的功能是外部的!像任何其他函数一样,用:outer调用它。现在您得到一个TypeError,因为调用者不是函数

这种“双重呼叫”被称为

代码也可以这样重写。 唯一的区别是内部现在也可以在外部作用域中访问,而外部作用域是。 看

常量内部=调用方=>{ 呼叫者某物; }; 常量外部==>内部; inner充当返回函数outer的角色。 它将函数作为参数,并使用某个对象作为参数调用它

outer只是一个返回函数inner的函数,其他什么都不返回。 它不呼叫它,呼叫时它不接触 呃,跟什么都没有关系

外部和内部是相同的

另一方面,如果我省略它并编写代码[没有调用者],这两个函数FirstFunction和secondFunction将不会执行。那么,打电话的人到底是怎么说的 — 或者不管它叫什么 — 工作

首先,让我们修复语义:FirstFunction和secondFunction是函数调用。 它们是否是函数,取决于FirstFunction和secondFunction返回什么。 FirstFunction和secondFunction是函数,至少代码表明它们是函数

更具体地,考虑警戒:

警报是一种功能;你可以把它叫做警报。 警报不是一种功能;你不能像警报一样叫它。 调用者是一个回调函数。 如果您在代码中省略了caller,那么myFunction将是正确的调用,它不会抛出错误,只调用firstFuction和secondFunction

但是回调的目的是将FirstFunction和secondFunction的结果传递给函数调用方。 您必须自己提供该功能,例如警报功能

myFunctionalert调用内部函数,向其传递警报。 内部函数调用FirstFunction和secondFunction,并将其结果传递给调用者,我们将其指定为警报

一旦我像调用myFunction一样调用它,你能告诉我它是如何工作的吗

很简单,这里什么也没发生。 myFunction返回一个函数,就这样;该函数没有被进一步使用,因此被丢弃

高阶函数有一个关键方面没有在本代码中演示:封装值。 考虑这个代码:

const add=a=>{ 让计数=0; 返回b=>{ ++计数; log`将${a}添加到其他对象的函数已被调用${count}次。`; 返回a+b }; }; add和b的工作方式与以前的myFunction和caller类似,但现在,外部函数也需要一个参数,因此add没有帮助。 add5调用add函数并将参数a设置为5。 此外,add53调用内部返回函数,将b设置为3并返回8

但是在add中还有一些状态,它是一个名为count的变量

常数addFive=add5; console.logaddFive3;//印刷品8。 //但也记录:向其他内容添加5的函数已被调用1次。 console.logaddFive10;//打印15张。 //但也记录:向其他内容添加5的函数已被调用2次。 计数只能在外部内部访问,包括内部的任何功能;它是“封装的”。 这是隐藏某些状态的常用方法,这些状态应该只能在特定函数中访问

a实际上也封装在add…;a和count具有相同的作用域,彼此之间没有太大区别,只是在调用add时可以将a设置为参数,而count不能

然后,您添加了更多上下文,其中调用看起来更像这样:

const myFunction = () => {
   return function () {
     firstFuctnion();
     secondFunction();
   };
 };
其他函数我的函数 这与之前的情况不同,之前您只编写了类似myFunction的调用。 现在,结果不会被丢弃,因为它被输入到原始代码中的其他函数中:store.dispatch

[caller]没有作为参数传递,也没有在任何地方定义

但是现在,另一个函数的任务是使用适当的回调函数作为参数调用myFunction。 现在,您不需要自己传递函数;取而代之的是,其他函数为您执行此操作

将此与。 如果返回前面的sum示例函数,则可以自己传递参数:

sum1,2; 或者某个库或框架为您提供:

//库代码 const dotherlightthing=callback=>callback1,2; //你的代码 多瑟莱特森; 或内置或主机定义的函数为您执行以下操作:

[1,2,3]。还原度为0; 这些参数来自何处或函数从何处调用都无关紧要。 但是它被调用了,并且在某个地方用正确的参数调用了它

1:高阶函数的两个定义是

返回函数的函数,或 将另一个函数作为参数的函数。 外层符合第一个定义。 外部独立且巧合地符合第二个定义

2:好吧,当然,sum也不会抛出错误,但是a和b都是未定义的。undefined+undefined具有不会导致错误的语义,但希望您能理解这一点:在原始代码中,myFunction会抛出错误,只是因为undefinedfirstFunction不可能。罪魁祸首相同:调用方未定义。

相关:。“调用方参数实际上没有定义”是什么意思?可以说,那个论点还没有进入方程。myFunction是一个需要为其提供调用方参数的函数,例如myFunctionalert。或者换一种说法,“为什么我没有出错?” — 出于同样的原因
y函数suma,b{返回a+b;};总和尽管未提供a和b,但不会抛出错误;需要这些参数的函数还没有被调用。你需要使用myFunction来访问内部函数。你已经得到了一些很好的答案,所以我不打算写一篇文章。在redux thunk的情况下,thunk中间件允许您调度一个动作,它是一个调度函数,而不仅仅是一个普通的动作对象。内部函数在发送到商店时由thunk中间件调用。由于redux thunk,dispatch接受函数。您没有调用函数,仅此而已。相关:。“调用方参数实际上没有定义”是什么意思?可以说,那个论点还没有进入方程。myFunction是一个需要为其提供调用方参数的函数,例如myFunctionalert。或者换一种说法,“为什么我没有出错?” — 出于同样的原因,函数suma,b{返回a+b;};总和尽管未提供a和b,但不会抛出错误;需要这些参数的函数还没有被调用。你需要使用myFunction来访问内部函数。你已经得到了一些很好的答案,所以我不打算写一篇文章。在redux thunk的情况下,thunk中间件允许您调度一个动作,它是一个调度函数,而不仅仅是一个普通的动作对象。内部函数在发送到商店时由thunk中间件调用。由于redux thunk,dispatch接受函数。您没有调用您的函数,仅此而已。“您需要将该值分配给一个新变量” — 不,你不需要。“但请注意,由于上述原因,这将引发错误。” — OP已经对代码的工作方式感到困惑;为什么不告诉他们如何正确地打电话呢?你是对的,你可以求助于链锁,但从可能让他们困惑的外观来看,这就是为什么我求助于长时间的解决方案。他们问的问题没有目标,所以我只是回答了他们是什么阻碍了他们。问题很明显,您是对的,我们可以进一步解释。“您需要将值分配给一个新变量” — 不,你不需要。“但请注意,由于上述原因,这将引发错误。” — OP已经对代码的工作方式感到困惑;为什么不告诉他们如何正确地打电话呢?你是对的,你可以求助于链锁,但从可能让他们困惑的外观来看,这就是为什么我求助于长时间的解决方案。他们问的问题没有目标,所以我只是回答了他们是什么阻碍了他们。问题很明显,你是对的,我们可以进一步解释。感谢塞巴斯蒂安的详细解释。我通过了你的观点,我得到了你的观点。例如,关于您的解释,但回调的重点是将FirstFunction和secondFunction的结果传递给函数调用方。您必须自己提供该功能,例如警报功能。问题是,调用方所做的事情没有定义。我添加了整个代码,但我不明白的是,dispatch参数对我来说毫无意义…@VaclavVlcek在“您随后添加了更多上下文[…]”之后阅读了编辑后的答案。感谢Sebastian的详细解释。我通过了你的观点,我得到了你的观点。例如,关于您的解释,但回调的重点是将FirstFunction和secondFunction的结果传递给函数调用方。您必须自己提供该功能,例如警报功能。问题是,调用方所做的事情没有定义。我添加了整个代码,但我不明白的是分派参数对我来说毫无意义…@VaclavVlcek在“您随后添加了更多上下文[…]”之后阅读了编辑后的答案。感谢Ruban的解释。请再问一个问题:consttweeps=multipler2来自您的第一个代码片段。那是2号因子还是n?或者两者都有:我仍然不明白您需要两个参数:factor和n,但您最终只传递了一个数字2。谢谢你,祝你今天愉快@VaclavVlcek乘数是一个接受因子作为参数并返回函数的函数。所以,在乘数2中,因子变为2。此时,您不需要考虑内部功能。从精神上讲,它只是常量乘数=函数因子{return…something…;};。所有函数都不接受两个参数,因此您不需要传递两个参数。感谢Ruban的解释。请再问一个问题:consttweeps=multipler2来自您的第一个代码片段。那是2号因子还是n?或者两者都有:我仍然不明白您需要两个参数:factor和n,但您最终只传递了一个数字2。谢谢你,祝你今天愉快@VaclavVlc ek乘数是一个接受因子作为参数并返回函数的函数。所以,在乘数2中,因子变为2。此时,您不需要考虑内部功能。从精神上讲,它只是常量乘数=函数因子{return…something…;};。所有函数都不接受两个参数,因此不传递两个参数。