Javascript 返回函数的函数

Javascript 返回函数的函数,javascript,Javascript,我一直坚持“返回函数的函数”的概念。我指的是Stoyan Stefanov的《面向对象Javascript》一书 片段一: 函数a(){ 警惕('A!'); 函数b(){ 警报('B!'); } 返回b(); } var s=a(); 警报(“中断”); s()返回函数名而不返回()返回对函数的引用,可以像使用var s=a()那样分配该函数s现在包含对函数b()的引用,调用s()在功能上等同于调用b() 在return语句中使用()调用函数将执行该函数,并返回该函数返回的任何值。它类似于调用

我一直坚持“返回函数的函数”的概念。我指的是Stoyan Stefanov的《面向对象Javascript》一书

片段一:

函数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
ing
typeof(s)
。代码段b将为您提供“函数”。代码片段a会给你什么?

返回b()
调用函数b(),并返回其结果


返回b返回对函数b的引用,您可以将其存储在变量中以供以后调用。

返回
b
是返回函数对象。在Javascript中,函数只是对象,就像任何其他对象一样。如果你觉得没有帮助,就用“东西”代替“对象”。可以从函数返回任何对象。您可以返回真/假值。一个整数(1,2,3,4…)。您可以返回一个字符串。可以返回具有多个属性的复杂对象。您可以返回一个函数。函数只是一种东西

在您的例子中,returning
b
返回对象,对象是一个可调用的函数。Returning
b()
返回可调用函数返回的值

考虑以下代码:

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 ) );