0

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

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: stevenAND INNER: steven。这是为什么?

4

3 回答 3

3
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()();
于 2020-06-15T23:22:21.110 回答
0

printName()做两件事:

1)它console.log是全局变量的值myName

2) 它return是一个名为 的函数printAgain

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

于 2020-06-15T23:28:16.497 回答
0

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

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

“外部”函数 ,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"输出。

在这种情况下,这些都与您使用函数声明还是函数表达式无关。

于 2020-06-15T23:22:03.197 回答