JavaScriptで巡回中のクローズド問題の探究


もっと素晴らしいです.石切り労働者の大聖堂です.
何の問題ですか?jì/
JavaScriptの中で循環に関する最も一般的な誤りを見てみましょう.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var items = [ {"id": "email"}, {"id": "name"}, {"id": "age"}, ]; function setupHelp() { var helpText = [ {'id': 'email', 'help': 'Your e-mail address'}, {'id': 'name', 'help': 'Your full name'}, {'id': 'age', 'help': 'Your age (you must be over 16)'} ]; for (var i = 0; i < helpText.length; i++) { var item = helpText[i]; // Bind help function to this item. items[i].help = function() { console.log(item.help); } } } setupHelp(); for (var i = 0; i < items.length; i++) { items[i].help(); } 
多くのwebの先の友達が見覚えがあると思います.このコードは、長いが、意味がないが、いくつかの要素を遍歴し、対応する要素に対応する方法、例えばhelp方法をバインドする、フロントエンドコードによくあるシーンである.
このコードがどのように実行されても、結果はいつも以下の通りです.
[cipher@Rose test_js]$ node a.js
Your age (you must be over 16) Your age (you must be over 16) Your age (you must be over 16) 
そうであることを知っていて,だからそうなのだと知っている.
このコードは多くの知識を含んでいますが、二言三言では説明できません.
尊敬する先輩はこう言います.
「何日間かかっても説明がつかないと理解が足りないということです.」
ですから、一応の語句をいくつか使って説明してみましょう.
  • このコードは、結合方法としてクローズチャームを使用する.
  • closureは、作成時のenvironmentを常に覚えています.(これはクローズアップの大きな特徴です.)
  • Tip
    Cloosures are functions that refer to independent(free)variables.
    In other words,the function defined in the closure‘remembers’the environment in which it created.
    はい、ここまでです.これはクローズアップの特性によるものだと知っています.しかし、この特性は人にミスをしやすいのに、なぜこの特性を設計しなければならないですか?
    存在は合理的である.
    closureはいくつかのデータ(環境)を一つの関数に結びつけることができるようにする.
    ちょっと耳慣れていますか?
    OOP(Object Oriendted Programming)は、同様に属性/方法をオブジェクトと結合することにより、オブジェクト指向プログラミングを実現するためである.
  • は、1回限りの方法を1つのオブジェクトに結びつけることができる
  • .
    このようなシーンはwebフロントエンドでよく見られます.JavaScriptはイベントに基づいています.まず行為を定義し、ユーザーがイベントをトリガした後(マウスクリックやEnterキー入力など)に実行します.
    私たちが最初に見たのはこのような応用シーンです.
    もっと高級な使い方があります.
  • closureシミュレーションオブジェクトを使用したprvate methods
  • JavaScript原生はプライベートメソッドを作成する概念を提供していませんが、closureを通じて「曲線救国」を実現できます.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } }; var counter1 = makeCounter(); var counter2 = makeCounter(); alert(counter1.value()); /* Alerts 0 */ counter1.increment(); counter1.increment(); alert(counter1.value()); /* Alerts 2 */ counter1.decrement(); alert(counter1.value()); /* Alerts 1 */ alert(counter2.value()); /* Alerts 0 */ 
    同じように、この例は丸印可能な点も非常に多いです.
  • は匿名の関数を通して、ここで三つの関数によって作成されました.counter.increment、counter.decrement、counter.valueによって共有される実行環境です.
  • この共有実行環境は、2つのプライベートデータを含む.変数prvateCounterと関数changeBy.これらの2つは匿名関数以外の他のオブジェクトにアクセスできません.匿名関数内の3つの共通関数だけでアクセスできます.
  • したがって、MakeCounterの実行が終了しても、その帰りのオブジェクトcounter 1は、生成時の環境のすべての変数にアクセスすることができる.
  • 最後に、これは共有環境であるにもかかわらず、counter 1とcounter 2にとっては依然として独立している.したがって、counter 1とcounter 2が訪問するprvateCounterは完全に独立しています.
  • 問題をどう解決しますか?
    closureを話し終わったら、どうやって冒頭の問題を解決するかを話しましょう.
    まずコンセプトを紹介します.
    IIFとは何かを理解するには、まずIIIFEとは何かを知っておくべきです.
    簡単な例を見てください.
    1
    function() { return "I'm statement"; }; 
    このコードは匿名関数を定義しています.
    nodeを使ってこのコードを実行します.
    [cipher@Rose test_js]$ node
    > var foo = function() { return "I'm statement"; };
    undefined
    > foo [Function] 
    foo変数は匿名関数を指します.
    括弧を使ってfunctionキーを含むと、式になります.
    1
    (function() { return "I'm expression"; }()); 
    したがって、このコードは匿名関数だけでなく、表式でもある.
    node実行を使う:
    [cipher@Rose test_js]$ node
    > var foo = (function() { return "I'm expression"; }());
    undefined
    > foo 'I\'m expression' 
    このとき、foo変数は文字列を指します.
    これはBen Almanが提案したJavaScript IIIIIIFEを利用しているものです.
  • JavaScriptでは、括弧(()は語句を含んではいけません.
  • IIFを作成して、式をすぐ実行します.
    この考え方でIIIIFEを定義し、変数iを保存することができます.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    var items = [ {"id": "email"}, {"id": "name"}, {"id": "age"}, ]; function setupHelp() { var helpText = [ {'id': 'email', 'help': 'Your e-mail address'}, {'id': 'name', 'help': 'Your full name'}, {'id': 'age', 'help': 'Your age (you must be over 16)'} ]; for (var i = 0; i < helpText.length; i++) { // What's different? (function(lockedIndex) { var item = helpText[lockedIndex]; // Bind help function to this item. items[lockedIndex].help = function() { console.log(item.help); } }(i)); } } setupHelp(); for (var i = 0; i < items.length; i++) { items[i].help(); } 
    IIIIFにより、変数iを変数lockedIndexに「ロック」しました.
    このように、helpが指す匿名関数から引用されるitem変数はiと一対一に対応する.
    修正したコードを実行した結果:
    [cipher@Rose test_js]$ node a.js
    Your e-mail address
    Your full name
    Your age (you must be over 16) 
    IIFには2つの表現があります.
    //         (function(parameters){ /* code */ }(arguments)); (function(parameters){ /* code */ })(arguments); 
    Tip AgugmentAn expressisition in the compma-separated list bounded bythe parentheses in a method or instance conststststststorcation cal Expression or bounded bythe squararararararare backetsn n n eleeemenacaccess expressisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisisision.It.It.It.It.It.It isisisisor indexer definition、which acquires a value on entry to that function member.It is also known as formal parameter.
    締めくくりをする
    一般的な循環閉込めの例を通して、
    なぜこのような一般的なエラーが発生したのかを説明した.
    また、どのようにこのようなエラーを解決しますか?IIIFE「ロック」変数(またはJavaScriptの特性)を利用します.
    同時に、関連する知識点の具体的な説明を出しました.
    読書を勧める
    もしあなたもよく分からないなら、続きを読むことを勧めます.
  • JavaScript IIF
  • JavaScript Cloosures
  • JavaScript Module Pattern
  • ECMA-622-3 in detail.Chapter 5.Functions.
  • JavaScript Function
  • Named Function
  • JavaScript Module Pattern In Depth
  • [1]
    JavaScript Cloosures
    [2]
    JavaScript IIIIFE