学习闭包,我写了一个函数,该函数返回一个函数,该函数将名称打印到控制台:
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: steven
和INNER: 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(。