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…;};。所有函数都不接受两个参数,因此不传递两个参数。