为什么我的函数调用仅在函数是表达式时才有效,而不能在函数声明时起作用?



学习闭包,我写了一个函数,该函数返回一个函数,该函数将名称打印到控制台:

let myName = 'steven';
function printName() {
console.log(`OUTER: ${myName}`);
return function printAgain() {
console.log(`INNER: ${myName}`);
};
}
printName(); //Only prints 'OUTER: steven'
const newFunc = printName();
newFunc(); //Prints 'OUTER: steven' 
//AND 'INNER: steven'

为什么只有在使用函数表达式时才调用内部函数?为什么函数声明只运行外部控制台日志,当我使用 printName(( 调用它而不是第二个时?

同样,如果我在没有偏执的情况下调用我的函数表达式newFunc,它只会打印OUTER: steven. 但是,如果我使用括号并将其称为newFunc(),它会同时打印OUTER: stevenINNER: steven。为什么?

newFunc(); //Prints 'OUTER: steven' 
//AND 'INNER: steven'

你的评论不太正确。在这里它们是固定的:

printName(); //Only prints 'OUTER: steven'
const newFunc = printName(); //Only prints 'OUTER: steven' 
newFunc(); //Only prints 'INNER: steven'

当你调用printName()时,外部函数运行并命中第一个日志语句。然后创建一个新函数,并返回。内部函数不会自动发生任何事情;这完全取决于您之后如何处理它。

在您的第一个示例中,您永远不会对返回的函数执行任何操作。由于您不调用返回的函数,因此它不会执行,因此不会记录任何内容。在第二个示例中,您确实对返回的函数执行了一些操作,将其保存到变量中,然后调用它。通过调用它,您可以使其记录第二条消息

注意:是否将新函数分配给变量实际上并不重要,重要的是调用它。以下内容将打印出两个日志语句:

printName()();

看来你在这里误解了事情。在您的示例中:

function printName() {
console.log(`OUTER: ${myName}`);
return function printAgain() {
console.log(`INNER: ${myName}`);
};
}

"outer"函数printName,每当执行时都会记录"OUTER"字符串。此执行还恰好返回一个新函数,即"内部"函数。这将在执行时记录"INNER"字符串。

因此,逐步完成原始代码的其余部分:

printName(); //Only prints 'OUTER: steven'

这将执行外部函数,因此记录您记下的输出。它还返回一个新函数,但由于您没有将其分配给变量或以其他方式对其进行任何操作,因此我们不会观察到这一点。请注意,如果要执行此返回的函数(例如printName()()(,您将看到打印"OUTER",后跟"INNER"

这正是您随后要做的事情,尽管分为两个阶段:

const newFunc = printName();
newFunc(); //Prints 'OUTER: steven' 
//AND 'INNER: steven'

您完全正确,但不是每行正在做什么。"OUTER"输出来自const newFunc = printName(),它执行printName。然后,newFunc()调用返回的函数(内部函数(,因此记录"INNER"输出。

在本例中,这些都与使用函数声明还是函数表达式无关。

printName()做两件事:

1(它console.log全局变量myName的值。

2(它return一个名为printAgain的函数。

您调用printName()是因为您想为const newFunc分配一个值(上面提到的项目 2(,但您必须意识到每次调用printName()时都会调用其console.log(上面提到的项目 1(。

最新更新