0

私はスコープ、特にクロージャーに頭を悩ませようとしてきました。このトピックに関する投稿がたくさんあることを知っており、たくさん読んでいます。しかし、ほとんどの場所では、このトピックを高度なトピックと呼んでおり、比較的理解しにくい用語を使用しています。関数が実際にどのように機能するかについて間違った考えを持って、より複雑なトピックに踏み込むことがないように、基本を正しく理解していることを絶対に確認したいと思います。

だから...私は基本的な機能を選びました.ボンネットの下で起こっていると思うことが実際に起こっていることであるかどうか誰かに教えてもらいたいです.

これはコードです:

function sum(a) {


  return function(b) {  
    return a+b
  }
}

console.log( sum(1)(sum(2)))

(実際には合計を行うわけではないことを知っています。各ステップで何が起こっているのかを理解しようとするために微調整しました。)

したがって、私の主な疑問は、なぜ A が 2 ではなく 1 であったかということでした。によって返された直後に、引数としてfunction(b)取るために が作成されるとすぐに、クロージャーが作成されるという結論に達しました。したがって、クロージャーの定義により、関数が作成された時点で、レキシカル環境も保存されると想定しています ( where )。これは正しいですか?sum(2)sum(1)a = 1

手順を図にしました。

ダイアグラム

4

3 に答える 3

-1

ここで何が起こっているのか

1)関数が関数を返し、その返された関数がすぐに呼び出される場合、それが呼び出されますcurrying(関数型プログラミング用語)。curryingこの例では、closure両方の概念が混在しています。

2)最初にあなたのsum(1)部分が呼び出されます。これは (#1st と呼びましょう) を返しますが、#1st のコンテキストでのみ 1 としてfunction(b) {return a+b}存続します。a

3)関数の引数は関数呼び出し自体であるため、その引数部分が呼び出されます。たとえばsum(1)(sum(2))、ここでsum(2)part が呼び出されて戻りますfunction(b) {return a+b}(これを #2nd と呼びます)。また、#2nd のみのコンテキストで 2 として存続aします (クロージャ)。

4) ここで、そのカリー化構文のパラメーターとして #2nd を使用して #1st をすぐに呼び出します - #1st(#2nd)

5)したがって、私たちのa変数は割り当てられておらず、値があり1b変数には値がありますfunction(b) {return a+b}。これら2つを連結しているので、最終的な出力は1function(b) {return a+b}

NB - a) a+b の合計が必要で、その奇妙な出力が必要な場合は、最終行をconsole.log(sum(1)(2)). b) a#2nd と呼ばれる関数の値が 2 のクロージャーが、 alive 以外の場所で使用されていないことに気付いた場合。

于 2016-04-30T02:56:32.260 に答える
-1

内部関数をレキシカル スコープの外に移動するために使用する機能が何であれ、それは最初に宣言された場所へのスコープ参照を維持し、それを実行するたびにそのクロージャが実行されます。

次の関数では、これが呼び出されなくなった場合でも関数内で宣言されgreetた変数を使用する方法を確認します。これはクロージャと呼ばれます。salutegreeting

function greeting(name) {
  var salute = "Hello "; // This is a closure

  return function() {
    console.log(salute + name);
  }
}

var greet = greeting("Dave");

greet();    // Hello Dave

Kyle Simpson の書籍シリーズYou Don't Know JSでクロージャについてさらに多くを学ぶことができますが、この特定のトピックについてはYou Don't Know JS: Scope & Closures を確認してください。彼は、このような難しい概念を説明するために、シンプルで適切な言語を使用しています。

于 2016-04-30T02:20:23.750 に答える