我坚持使用'返回函数的函数'这个概念。我指的是Stoyan Stefanov撰写的“面向对象的Javascript”一书。
Snippet One:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b();
}
var s = a();
alert('break');
s();
输出:
A!
B!
break
Snippet Two
function a() {
alert('A!');
function b(){
alert('B!');
}
return b;
}
var s = a();
alert('break');
s();
A!
break
B!
有人可以告诉我在上述代码段中返回b
和b()
之间的区别吗?
答案 0 :(得分:98)
为函数指定变量(不带括号)复制对函数的引用。将括号放在函数名的末尾,调用函数,返回函数返回值。
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'
该功能仍可调用。它仍然存在。这在JavaScript中一直使用。函数可以像其他值一样在 周围传递。请考虑以下事项:
function counter() {
var count = 0;
return function() {
alert(count++);
}
}
var count = counter();
count();
count();
count();
函数计数可以保留在其外部定义的变量。这称为闭包。它在JavaScript中也经常使用。
答案 1 :(得分:42)
返回不带()
的函数名称会返回对函数的引用,该函数可以像var s = a()
一样分配。 s
现在包含对函数b()
的引用,并且调用s()
在功能上等同于调用b()
。
// Return a reference to the function b().
// In your example, the reference is assigned to var s
return b;
在return语句中使用()
调用函数执行函数,并返回函数返回的任何值。它与调用var x = b();
类似,但不是指定b()
的返回值,而是从调用函数a()
返回它。如果函数b()
本身没有返回值,则在undefined
完成其他任何工作后,调用将返回b()
。
// Execute function b() and return its value
return b();
// If b() has no return value, this is equivalent to calling b(), followed by
// return undefined;
答案 2 :(得分:29)
return b();
调用函数b(),并返回其结果。
return b;
返回对函数b的引用,您可以将其存储在变量中以便稍后调用。
答案 3 :(得分:15)
返回b
返回一个函数对象。在Javascript中,函数只是对象,就像任何其他对象一样。如果您发现没有帮助,只需将“对象”替换为“对象”即可。您可以从函数返回任何对象。您可以返回true / false值。整数(1,2,3,4 ......)。你可以返回一个字符串。您可以返回具有多个属性的复杂对象。你可以返回一个功能。功能只是一件事。
在你的情况下,返回b
返回的东西,东西是一个可调用的函数。返回b()
将返回可调用函数返回的值。
考虑以下代码:
function b() {
return 42;
}
使用上面的定义,return b();
返回值42.另一方面,return b;
返回一个函数,它本身返回值42.它们是两个不同的东西。
答案 4 :(得分:3)
当你返回b
时,它只是对函数b的引用,但此时没有被执行。
当您返回b()
时,您正在执行该函数并返回其值。
在示例中尝试alert
typeof(s)
。代码片段b将为您提供“功能”。会给你什么片段?
答案 5 :(得分:2)
将函数想象为类型,就像int一样。您可以在函数中返回整数。 您也可以返回函数,它们是“函数”类型的对象。
现在语法问题:因为函数返回值,你怎么能返回一个函数而不是它的返回值?
省略括号!因为没有括号,该功能将不会被执行!所以:
return b;
将返回“函数”(想象一下,如果你要返回一个数字),同时:
return b();
首先执行函数然后返回执行它获得的值,这是一个很大的区别!
答案 6 :(得分:2)
创建变量:
var thing1 = undefined;
声明功能:
function something1 () {
return "Hi there, I'm number 1!";
}
提醒thing1
(我们的第一个变量)的值:
alert(thing1); // Outputs: "undefined".
现在,如果我们希望thing1
成为函数something1
的引用,意味着它与我们创建的函数相同,我们会这样做:< / p>
thing1 = something1;
但是,如果我们想要函数的return
值,那么我们必须为它分配执行函数的返回值。您可以使用括号执行该函数:
thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!"
答案 7 :(得分:0)
这在现实生活中非常有用。
因此,您的常规express
路线如下所示:
function itWorksHandler( req, res, next ) {
res.send("It works!");
}
router.get("/check/works", itWorksHandler );
但是如果你需要添加一些包装器,错误处理程序或smth呢?
然后你从包装器中调用你的函数。
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 ) );
最后看到你传递的函数loggingWrapper
有一个参数作为另一个函数itWorksHandler
,你的loggingWrapper
返回一个以req, res, next
为参数的新函数
答案 8 :(得分:-1)
片段一:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b(); //return nothing here as b not defined a return value
}
var s = a(); //s got nothing assigned as b() and thus a() return nothing.
alert('break');
s(); // s equals nothing so nothing will be executed, JavaScript interpreter will complain
语句'b()'意味着执行名为'b'的函数,该函数显示一个带有文本'B!'的对话框。
语句'return b();'表示执行名为“ b”的函数,然后返回“ b”返回的函数。但是'b'不返回任何内容,因此该语句'return b()'也不返回任何内容。 如果b()返回数字,那么“ return b()”也是数字。
现在's'被赋予返回'a()'的值,该值返回'b()',它什么也不是,所以's'什么都不是(在JavaScript中这实际上是一件事,它是'undefined'因此,当您要求JavaScript解释's'是什么数据类型时,JavaScript解释器会告诉您's'是未定义的。)由于's'是未定义的,因此当您要求JavaScript执行此语句's( )”,您要让JavaScript执行名为“ s”的函数,但是这里的“ s”是“未定义”而不是函数,因此JavaScript会抱怨:“嘿,s不是函数,我不知道”无法知道如何处理此s”,那么JavaScript会显示“未捕获的TypeError:s不是函数”错误消息(在Firefox和Chrome中进行了测试)
第二段
function a() {
alert('A!');
function b(){
alert('B!');
}
return b; //return pointer to function b here
}
var s = a(); //s get the value of pointer to b
alert('break');
s(); // b() function is executed
现在,函数“ a”返回指向名为“ b”的函数的指针/别名。因此,当执行's = a()'时,'s'将获得指向b的值,即's'现在是'b'的别名,调用's'等于调用'b'。即's'现在是一个函数。执行's()'意味着运行功能'b'(与执行'b()'相同),显示“ B!”的对话框将会出现(即运行'alert('B!');函数'b'中的语句)