Javascript 返回函数的函数
我一直坚持“返回函数的函数”的概念。我指的是Stoyan Stefanov的《面向对象Javascript》一书 片段一:Javascript 返回函数的函数,javascript,Javascript,我一直坚持“返回函数的函数”的概念。我指的是Stoyan Stefanov的《面向对象Javascript》一书 片段一: 函数a(){ 警惕('A!'); 函数b(){ 警报('B!'); } 返回b(); } var s=a(); 警报(“中断”); s()返回函数名而不返回()返回对函数的引用,可以像使用var s=a()那样分配该函数s现在包含对函数b()的引用,调用s()在功能上等同于调用b() 在return语句中使用()调用函数将执行该函数,并返回该函数返回的任何值。它类似于调用
函数a(){
警惕('A!');
函数b(){
警报('B!');
}
返回b();
}
var s=a();
警报(“中断”);
s()代码>返回函数名而不返回()
返回对函数的引用,可以像使用var s=a()
那样分配该函数s
现在包含对函数b()
的引用,调用s()
在功能上等同于调用b()
在return语句中使用()
调用函数将执行该函数,并返回该函数返回的任何值。它类似于调用var x=b()
,但不是指定b()
的返回值,而是从调用函数a()
返回它。如果函数b()
本身没有返回值,则在b()
完成任何其他工作后,调用将返回undefined
返回b
时,它只是对函数b的引用,但此时不执行
当您返回b()
时,您正在执行函数并返回其值
在示例中尝试使用alert
ingtypeof(s)
。代码段b将为您提供“函数”。代码片段a会给你什么?返回b()
调用函数b(),并返回其结果
返回b代码>返回对函数b的引用,您可以将其存储在变量中以供以后调用。返回b
是返回函数对象。在Javascript中,函数只是对象,就像任何其他对象一样。如果你觉得没有帮助,就用“东西”代替“对象”。可以从函数返回任何对象。您可以返回真/假值。一个整数(1,2,3,4…)。您可以返回一个字符串。可以返回具有多个属性的复杂对象。您可以返回一个函数。函数只是一种东西
在您的例子中,returningb
返回对象,对象是一个可调用的函数。Returningb()
返回可调用函数返回的值
考虑以下代码:
function b() {
return 42;
}
使用上述定义,返回b()代码>返回值42。另一方面返回b代码>返回一个函数,该函数本身返回值42。它们是两种不同的东西 将函数想象成一个类型,比如int。您可以在函数中返回int。
您也可以返回函数,它们是“function”类型的对象
现在的语法问题是:由于函数返回值,如何返回函数而不是返回值
省略括号!因为没有括号,函数将无法执行!因此:
return b;
将返回“函数”(想象一下,如果您返回一个数字),同时:
首先执行函数,然后返回通过执行它获得的值,这是一个很大的区别 创建一个变量:
var thing1 = undefined;
function something1 () {
return "Hi there, I'm number 1!";
}
声明一个函数:
var thing1 = undefined;
function something1 () {
return "Hi there, I'm number 1!";
}
提醒事物1
的值(我们的第一个变量):
现在,如果我们希望thing1
成为函数something1
的引用,这意味着它与我们创建的函数是一样的,我们会做:
thing1 = something1;
但是,如果我们想要函数的返回值
则必须为其分配已执行函数的返回值。使用括号执行函数:
thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!"
将变量赋值给函数(不带括号)会将引用复制到函数。将括号放在函数名的末尾,调用函数并返回函数返回值
在您的示例中,还定义了函数中的函数。例如:
function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
该函数仍然可以调用。它仍然存在。这一直在JavaScript中使用。函数可以像其他值一样传递。考虑以下事项:
function counter() {
var count = 0;
return function() {
alert(count++);
}
}
var count = counter();
count();
count();
count();
函数count可以保留在其外部定义的变量。这叫做闭包。它在JavaScript中也被大量使用。这在现实生活中非常有用
使用Express.js
因此,您的常规express
路线如下所示:
但如果您需要添加一些包装器、错误处理程序或smth呢
然后从包装器中调用函数
看起来很复杂?那么,这个怎么样:
请参见末尾,您正在传递一个函数loggingWrapper
,该函数将一个参数作为另一个函数itWorksHandler
,并且您的loggingWrapper
返回一个新函数,该函数将req,res,next
作为参数。片段一:
函数a(){
警惕('A!');
函数b(){
警报('B!');
}
return b();//此处不返回任何内容,因为b未定义返回值
}
var s=a()//s没有被分配为b(),因此a()没有返回任何内容。
警报(“中断”);
s();//s等于零,所以不会执行任何操作,JavaScript解释器会抱怨
语句“b()”表示执行名为“b”的函数,该函数显示一个文本为“b”的对话框
语句“return b();”表示执行名为“b”的函数,然后返回函数“b”返回的内容。但是“b”不返回任何内容,那么这个语句“return b()”也不返回任何内容。
如果b()返回一个数字,那么“return b()”也是一个数字
现在为“s”赋值的是“a()”返回的值,它返回的是“b()”,它什么都不是,所以“s”什么都不是(在JavaScript中,它实际上是一个“未定义”的东西)。因此,当您要求JavaScript解释“s”是什么样的数据类型时,JavaS
function a() {
alert('A');
}
//alerts 'A', returns undefined
function b() {
alert('B');
return a;
}
//alerts 'B', returns function a
function c() {
alert('C');
return a();
}
//alerts 'C', alerts 'A', returns undefined
alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());
alert("Function 'c' returns " + c());
function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
function counter() {
var count = 0;
return function() {
alert(count++);
}
}
var count = counter();
count();
count();
count();
function itWorksHandler( req, res, next ) {
res.send("It works!");
}
router.get("/check/works", itWorksHandler );
function loggingWrapper( req, res, next, yourFunction ) {
try {
yourFunction( req, res );
} catch ( err ) {
console.error( err );
next( err );
}
}
router.get("/check/works", function( req, res, next ) {
loggingWrapper( req, res, next, itWorksHandler );
});
function function loggingWrapper( yourFunction ) => ( req, res, next ) {
try {
yourFunction( req, res, next );
} catch ( err ) {
console.error( err );
next( err );
}
}
router.get("/check/works", loggingWrapper( itWorksHandler ) );