ホームページ >バックエンド開発 >PHPチュートリアル >javascript - インタビューの質問: なぜクロージャを使用するのですか?
この回答を読んだ後、あまりよく理解していないようです
私はJavaを勉強しています。今日のインタビュー中に、インタビュアーは匿名クラスについて言及し、Java 8 は Lamada スタイルを提供しており、JS にはクロージャーの概念もあると言いました。インタビュアーはクロージャとは何ですか?と尋ねました。なぜクロージャを使用するのでしょうか?
私は言いました:アクセスを制御するために使用されます。内部から外部にアクセスできますが、外部から内部にアクセスすることはできません。
面接官はこの答えにあまり満足していないようです。専門家はこの問題についてどう考えているでしょうか?
この回答を読んだ後、あまりよく理解していないようです
私はJavaを勉強しています。今日のインタビュー中に、インタビュアーは匿名クラスについて言及し、Java 8 は Lamada スタイルを提供しており、JS にはクロージャーの概念もあると言いました。インタビュアーはクロージャとは何ですか?と尋ねました。なぜクロージャを使用するのでしょうか?
私は言いました:アクセスを制御するために使用されます。内部から外部にアクセスできますが、外部から内部にアクセスすることはできません。
面接官はこの答えにあまり満足していないようです。専門家はこの問題についてどう考えているでしょうか?
クロージングはその名の通り、肉まんを肉まんに変えることです〜
蒸しパンは小麦粉だけでできており、中に餡を詰めると蒸しパンになります
包子は具材が入った蒸しパンです
クロージャは独自の動作環境に付属する機能です
Fa Geは自分のBGMを持ってくる男です~
「自分の動作環境を持ち込む」の意味を理解していない子供もいます〜
もう一度例を挙げてみましょう~
プログラマの皆さんはインスタントラーメンを食べたことがあるでしょう〜
普通のインスタントラーメンと何が違うのですか?
調味料パックをご持参ください。
調味料パックはインスタントラーメンの調理環境です。
麺を調理するプロセスを簡素化します。これにより、調理のスキルを習得しなくても、おいしい牛肉麺を楽しむことができます。
関数型プログラミングのクロージャは関数の調味料パッケージです。ユーザーが関数を呼び出すのに
便利。複雑な外部状態の維持について心配する必要はありません。
たとえば、Python はさまざまな方法でクロージャを使用します:
静的プライベート変数~
部分関数~
単一パラメータ化~
デコレータ~
...
これらの機能を使用すると、実際に他人が設定した調味料パッケージで「インスタントラーメン」を食べていることになります。
実際、私の理解では、クロージャの目的は変数の範囲を拡大することです。
関数の即時実行とクロージャの関係は何ですか
私の答えは比較的弱いので、興味がある場合は、Height Three によるスコープチェーンとクロージャの説明を読んでください。
今読んだ記事: 史上最も怒られたプログラミング言語 - JavaScript
著者の答えは正確ではなく、私がインタビュアーだったら満足できないでしょう。
簡単に言えば、クロージャとは、関数がオブジェクトとして返されるときに、外部変数が同伴されている場合にクロージャが形成されることを意味します。饅頭と餡を比べて饅頭になるという同級生の答えにとても共感しました。ほとんど冗談でしたが、理解はとても深かったです。
さらに詳しく知りたい場合は、Python のクロージャーについて詳しく説明した記事を参照してください。プログラミング言語は異なりますが、原理は同じです。
あなたの答えは範囲に関するものであり、終結に関するものではありません。そして、この答えも不正確な答えです。何が内部で何が外部なのかをまったく説明することはできません。
クロージャはこんな感じだと思います。関数が定義されているスコープ外で呼び出された場合でも、関数は定義されているスコープにアクセスします。この現象を閉鎖といいます。
具体的な用途はたくさんありますが、一般的な用途には、プライベート プロパティの作成、関数のカリー化などが含まれます。
---------------区切り線---------------
クロージャの本質は静的スコープであることを付け加えておきます。 JavaScript には動的スコープがないため、関数は定義時にスコープにアクセスするため、クロージャを実装できます。
他の回答では、クロージャーは独自の動作環境に付属する関数であると述べています。しかし実際のところ、JavaScript の関数はどれも独自の実行環境を伴う関数ではないでしょうか?すべての関数がクロージャであると信じている人もいます。これは確かに間違いではありませんが、実際にはクロージャを理解する上ではあまり意味がありません。普段このように関数を使っているので、クロージャが何なのか知らなくても問題ありません。ただ、グローバル スコープが大きな限界であることに気づいていないかもしれません。
私たちの一般的なクロージャ形式は、関数 a が関数 b をカバーし、その後関数 a が関数 b を返すというものです。そのため、関数 b が関数 a 以外の場所で実行されても、関数 a のスコープにアクセスできます。このうち、「関数a以外の場所で関数bが実行されたとき」にクロージャの真の威力が反映されます。
要するに、クロージャは静的スコープに基づいた単なるプログラミング手法です。インタビューの観点から、クロージャとは何かを答えたい場合は、まず静的スコープの特徴を説明し、次に「関数 a 以外の場所で関数 b が実行された場合」をクロージャとみなす点を強調する必要があります。バオの完全な答え。
ラムダ計算では 1 つの入力と 1 つの出力しか許可されないため、 lambda a, b: a + b
就等于lambda a: lambda b: a + b
はカリー化されます。
簡単に言えば、クロージャの定義は次のとおりです: 関数は、定義されたときにスコープにアクセスできます。
つまり、あなたが言及したアクセス制御は、クロージャの適用シナリオにすぎません。もちろん、クロージャとは何かという質問に答えなければ、面接官は当然不満を抱きます。
さらに、Java は実際にはクロージャをサポートしていません。匿名内部クラスはクロージャに似ていますが、実際には機能や実装の観点からクロージャとはみなされません。理由:
機能的には、匿名内部クラスでアクセスされる変数はfinalである必要があります(Java8は暗黙的にfinalを宣言します)
実装に関しては、匿名内部クラスでアクセスされる最終変数値は実際には外部からコピーされるため、実際には前のスコープにアクセスできません。そのため、final でなければなりません。
いわゆる「クロージャ」は、多くの変数とこれらの変数にバインドされた環境を持つ式 (通常は関数) を指します。したがって、これらの変数も式の一部です。
JavaScript でクロージャを作成する クロージャを説明するのにこれ以上良い方法はありません:
関数 b は関数 a 内にネストされており、関数 a は関数 b を返します。
このように、var c=a() を実行すると、変数 c は実際には関数 b を指します。 c() を再度実行すると、ウィンドウがポップアップして i の値が表示されます (初回は 1)。このコードは実際にクロージャを作成します。これは、関数 a の外側の変数 c が関数 a 内の関数 b を参照しているためです。つまり、関数 a の内部関数 b が関数 a の外側の変数によって参照されると、クロージャが作成されます。 。
実際、クロージャの一般的な記述形式によれば、簡単に言えば、それは関数内にネストされた関数です。チーム開発では、名前の競合を防ぐために、通常、対応するコードをクロージャー形式でラップし、グローバル スコープに公開されないようにします。ただし、内部変数がすぐに再利用されず、メモリ オーバーフローのリスクがあるという欠点があります。