私も最初はこれを理解するのに苦労しました。これが、一撃一撃で明確に到達した方法です。これはスタックに関する私の最初の投稿であり、それについて長々とすみません。
文字列を返す非常に基本的な関数を見てみましょう:
function fun() {
return 'Hi!';
}
呼び出し括弧なしで上記の関数をログに記録すると、コンソールは関数への参照をログに記録するだけです。
console.log(fun); //logs ---> [Function: fun]
もう一度ログに記録しますが、呼び出し括弧を使用すると、次のようになります。
console.log(fun()); //logs ---> Hi!
関数の呼び出しは、その戻り値と同じです。
console.log(fun() === 'Hi!'); //logs ---> true
その上で、関数を書き直して、文字列を返す別の関数を内部で宣言しましょう。外側の関数は、内側の関数の呼び出しを返します。
function funAgain() {
function innerFun() {
return 'Hello there!';
}
return innerFun();
}
したがって、funAgain のスコープ内 (innerFun() === 'Hello there!') は true と評価されるため、funAgain の呼び出しをコンソールに記録すると、次のようになります。
console.log(funAgain()); //logs ---> 'Hello there!'
しかし、外部関数の return ステートメントで innerFun の呼び出し括弧を省略したらどうなるでしょうか?
function funAgain() {
function innerFun() {
return 'Hello there!';
}
return innerFun;
}
console.log(funAgain()); //logs [Function: innerFun]
関数 ITSELF が返されます。実際にはすべての話ではありませんが、(funAgain() === innerFun) と考えることができます。明らかに、スコープの問題のため、実際にこの比較を実際に実行することはできません (innerFun は funAgain の呼び出しの外に存在することはできません)。 . しかし!ちょっとそんな風に考えてみましょう。つまり、funAgain の戻り値を変数に取り込むと、次のようになります。
var innerFunCaptured = funAgain();
console.log(innerFunCaptured); // logs [Function: innerFun]
ここでも概念的には (innerFunCaptured === innerFun) ...
変数が内部関数にバインドされたので、変数に括弧を追加してその内部関数を呼び出すことができます。
console.log(innerFunCaptured()); //logs ---> 'Hello there!'
上記の「全体の話」について話していたとき、私が省略したのは、内部関数の変数へのバインディングは外部関数の呼び出しの結果であるため、実際にはバインディングには innerFun 自体だけでなく、それが存在する環境も含まれるということです。外部関数の呼び出しを介して渡される潜在的な引数を含めて作成されました。これにより、次のことが可能になります...
相互作用するパラメーターを持つように、外側と内側の関数をもう一度書き直します。
function funOnceMore(greetingPartOne) {
function innerFun(greetingPartTwo) {
return greetingPartOne + ' ' + greetingPartTwo;
}
return innerFun;
}
funOnceMore を引数付きでログに記録するとどうなるでしょうか。
console.log(funOnceMore('Hello')) //logs ---> [Function: innerFun]
ここでも、innerFun 自体が返されます。しかし、渡した引数 greetingPartOne はどうなるでしょうか。まあ、問題なく渡されましたが、funOnceMore 内で innerFun が呼び出されなかったため、 greetingPartOne が意味のある方法で使用されることはありませんでした。innerFun を呼び出す方法を理解する必要があります。答え: 前のステップで行ったように、変数にバインドする必要があります。
var innerFunCapturedAgain = funOnceMore('Hello')
これで、innerFunCapturedAgain は、innerFun と、渡した引数 'Hello' を持つ funOnceMore の環境を保持します。
これで、innerFunCapturedAgain に括弧を付けて innerFun を呼び出すことができます。これらの括弧は、innerFun に渡す greetingPartTwo の引数をカプセル化します。
console.log(innerFunCapturedAgain('there!')) //logs ---> 'Hello there!'