返回函数的函数

我被“返回函数的函数”这个概念所困扰,我指的是 Stoyan Stefanov 的书“面向对象的 Javascript”。

片段一:

function a() {
alert("A!");


function b() {
alert("B!");
}


return b();
}


var s = a();
alert("break");
s();

产出:

A!
B!
break

片段二

function a() {
  

alert('A!');


function b(){
alert('B!');
}


return b;
}


var s = a();
alert('break');
s();

产出:

A!
break
B!

谁能告诉我在上面的代码片段中返回 b和返回 b()的区别?

311108 次浏览

返回不包含 ()的函数名将返回对函数的引用,可以像使用 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()本身不返回值,那么在 b()完成其他任何工作之后,调用返回 undefined

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

返回 b时,它只是对函数 b 的引用,但此时不执行。

当返回 b()时,您正在执行函数并返回其结果。

在示例中尝试 alertingtypeof(s)。代码片段 b 将给你“函数”。代码片段 a 将给你什么?

return b();调用函数 b ()并返回其结果。

return b;返回对函数 b 的引用,可以将其存储在一个变量中以便稍后调用。

返回 b就是返回一个函数对象。在 Javascript 中,函数只是对象,就像任何其他对象一样。如果你觉得这样没有帮助,只要把“ object”换成“ thing”就行了。可以从函数返回任何对象。可以返回 true/false 值。一个整数(1,2,3,4...)。可以返回一个字符串。可以返回具有多个属性的复杂对象。你可以返回一个函数。函数只是一个东西。

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

考虑下面的代码:

function b() {
return 42;
}

使用上面的定义,return b();返回值42。另一方面,return b;返回一个函数,该函数本身返回值42。这是两码事。

把函数想象成一个类型,就像一个 int 类型,你可以在函数中返回 int 类型。 你也可以返回函数,它们是“ function”类型的对象。

现在的语法问题是: 因为函数返回值,你怎么能返回一个函数而不是它的返回值?

因为如果没有括号,函数就不会被执行! 所以:

return b;

将返回“函数”(想象一下,如果你返回一个数字) ,同时:

return b();

首先执行函数 那么返回通过执行它得到的值,这是一个很大的区别!

创建一个 变量:

var thing1 = undefined;

声明 功能:

function something1 () {
return "Hi there, I'm number 1!";
}

提醒 thing1价值(我们的第一个变量) :

alert(thing1); // Outputs: "undefined".

现在,如果我们希望 thing1是函数 something1参考文献,这意味着它和我们创建的函数是一样的,我们会这样做:

thing1 = something1;

但是,如果我们想要函数的 return 价值,那么我们必须为它分配已执行函数的返回值。使用括号执行函数:

thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!"

为函数赋值一个变量(不带括号)会复制对该函数的引用。将括号放在函数名的后面,调用函数,返回函数返回值。

演示

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 中也被广泛使用。

片段一:

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’被赋值为 what‘ a ()’return 的值,返回‘ b ()’,它是空值,所以‘ s’是空值(在 JavaScript 中它实际上是一个东西,它是一个未定义的东西)。因此,当您要求 JavaScript 解释“ s”是什么数据类型时,JavaScript 解释器将告诉您“ s”是未定义的。)因为‘ s’是未定义的,当你要求 JavaScript 执行这个语句‘ s ()’时,你是在要求 JavaScript 执行一个名为‘ s’的函数,但是这里的‘ s’是一个‘未定义的’,而不是一个函数,所以 JavaScript 会抱怨,“嘿,s 不是一个函数,我不知道如何处理这个 s”,然后一个“未捕获的 TypeError: s 不是一个函数”错误消息将由 JavaScript 显示(在 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’现在是一个函数。Execute’s ()’表示运行函数‘ b’(与执行‘ b ()’相同) ,一个显示‘ B!’的对话框将出现(即运行’警报(’B!; 函数‘ b’中的语句)

这里有一个很好的例子来说明它在实践中是如何工作的:

当您使用两个参数调用并返回结果时

function sum(x, y) {
if (y !== undefined) {
return x + y;
} else {
return function(y) { return x + y; };
}
}


console.log(sum(3)(8))

还有另一种访问 js 中参数的方法:

function sum(x) {
if (arguments.length == 2) {
return arguments[0] + arguments[1];
} else {
return function(y) { return x + y; };
}
}

让我们用两个输出相同的例子来理解“ return”概念,一个没有使用“ return”概念,另一个使用“ return”概念,两者都给出相同的结果。

let myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy
}
addsToMyLuckyNumber(5, 2)


console.log(myLuckyNumber)

const myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)


console.log(myLuckyNumber, myNewLuckyNumber)
在第一个代码片段中,您可以看到代码

myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy

您不能为第二个代码片段分配类似的代码,因为它不会工作,所以我们使用“ return”概念并分配一个新变量。

function addsToMyLuckyNumber(incrementBy, multiplyBy) {
return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)