2016-07-29 5 views
0

電卓のアプリケーションを作成するためのJavaScriptコードを探していました。それは簡単ですが、私を混乱させるのは、関数を返す関数があるときです。関数を返す関数(Javascript)

以下のコードでは、クリックされたボタンに応じて関数が呼び出される「クリック」を利用するために、電卓の各ボタンがイベントリスナーを必要としていることを理解しています。 addValue(i)関数は、ボタンがクリックされたときにボタン値を結果フィールドに追加します。以下の関数は、関数を返す関数を持っています。関数呼び出しがなければ、結果は "789 + 456-123/0. = x"を返します。

addValue(i)関数がこの関数を機能させるために関数を返す必要がある理由を説明できます。

for (var i=0; i<buttons.length; i++) { 
    if(buttons[i] === "="){ 
     buttons[i].addEventListener("click", calculate(i)); 
    } else { 
     buttons[i].addEventListener("click", addValue(i)); 
    } 
} 

function addValue(i) { 
    return function() { 
     if(buttons[i].innerHTML === "÷") { 
      result.innerHTML += "/"; 
     } else if (buttons[i] === "x") { 
      result.innerHTML += "*"; 
     } else { 
      result.innerHTML += buttons[i].innerHTML; 
     } 
    } 
}; 
+4

JavaScriptのクロージャはどのように動作しますか?(http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Marty

答えて

-1

これを行う1つの方法:

for (var i=0; i<buttons.length; i++) { 
    (function(i) { 
     if(buttons[i] === "="){ 
      buttons[i].addEventListener("click", function() { calculate(i) }); 
     } else { 
      buttons[i].addEventListener("click", function() { addValue(i) }); 
     } 
    })(i); 
} 

をあなたはjavascript閉鎖hereについての詳細を読むことができます。

私は以下のMartyと一緒に集まったことから(あなたの質問を読み返して)、なぜあなたは関数を返す必要があるのか​​疑問に思います。 addEventListenerには、clickイベントが発生したときに呼び出される関数が必要です。あなたが直接関数を呼び出すのではないので(あなたはそれを実行しています)、渡されているパラメータが何であるかについて何の言い方もしていません。この場合、渡される唯一のパラメータは、クリックが発生した場所に関する情報、それが結ばれた要素に関する情報などを含むイベントオブジェクトです。別の関数でラップして値を渡す必要がありますiを実行する必要があります。 (私は上記の別の例を示しています)。

+2

downvoteを教えてください。 – FrankerZ

+0

あなたの「ここにこのコードがあります」という例は、OPがここに来て最初に理解しようとしてきたものの別の順列です... – Marty

+0

私は彼にコードを渡し、彼にさらに閉鎖を説明できるリンクを与えました。これはどのように問題ですか? – FrankerZ

1

この例では、私は、ウェブページのと類似の計算、と仮定している:、ボタンbuttons[i]を計算ボタンのいずれか

この場合
|---------------| 
|    | 
|---------------| 
| 1 | 2 | 3 | * | 
|---|---|---|---| 
| 4 | 5 | 6 |/| 
|---|---|---|---| 
| 7 | 8 | 9 | = | 
|---------------| 

あります。 | 1 || 5 |などのボタンの実際の数は、その指標であるので、buttons[2]| 2 |buttons[7]だろうなど、| 7 |だろうと私はbuttons[0]buttons[10]のように、他の値を推測している、演算子ボタン(| = || * |あります、|/|)。の表示だけで、ユーザはこれらのボタンのいずれかをクリックしたときに今、ボタンのinnerHtmlあるボタンの文字が、(結果のinnerHTMLに追加することで)電卓のresultに追加され

、操作。私は| * |そして、| 3 |をクリックしたのであれば、その後| 5 |、電卓はaddEventListenerが場に出たところです

|---------------| 
|   3*5 | 
|---------------| 
| 1 | 2 | 3 | * | 
|---|---|---|---| 
| 4 | 5 | 6 |/| 
|---|---|---|---| 
| 7 | 8 | 9 | = | 
|---------------| 

ようになります。 element.addEventListener("click", func)に電話すると、elementがクリックされるたびにfuncが呼び出されます。それがクリックされていますときに、結果にボタンを追加するために、あなたが行うことができます:

addButtonValueToResult
buttons[i].addEventListener("click", addButtonValueToResult); 

は結果にボタンの値を追加する機能です。

問題は、異なるボタンの値が異なるため、このような機能がすべての機能で機能しないことです。したがって、addButtonValueToResultは単純な関数にすることはできません。各ボタンにはそれぞれ独自の機能が必要です。

buttons[1].addEventListener("click", add1ToResult); 
buttons[2].addEventListener("click", add2ToResult); 
buttons[1].addEventListener("click", add3ToResult); 
... 

、その後のような機能があります:そのような解決策の1つは、ループのために捨てと同じような何かを行うことです

function add1ToResult() { 
    result.innerHTML += "1" 
} 

をしかし、あなたは機能を追加する必要があるため、これは、不必要な多くの作業を要します数字ボタン(| 1 || 9 |)とオペレータボタン(| = ||/|、および| * |)のそれぞれに対して、innerHtmlを結果に追加するだけです。さらに、ボタンのインデックスはすでに変数iに割り当てられており、ボタン全体はbuttons[i]のインデックスで参照できます。ボタンのインデックスiが与えられたときに、ボタンが(buttons[i]を介して)得られ、そのボタンの値が結果に追加されるように、各ボタンに対して自動的にプログラムを機能させることができませんでしたか?

これはまさにこのプログラムが行うことです:addValue(i)は、ボタンの内部値自体を追加するだけではありません。 は、特別なボタンのいくつかのテストケースでも、ボタンの内部値を追加する別の関数を返します。このコードを見る:

function addValue(i) { 
    return function() { 
     if(buttons[i].innerHTML === "÷") { 
      result.innerHTML += "/"; 
     } else if (buttons[i] === "x") { 
      result.innerHTML += "*"; 
     } else { 
      result.innerHTML += buttons[i].innerHTML; 
     } 
    } 
}; 

addValue(3)と言っていいでしょうか。これは数字3を結果に加える関数を返します。resultです。 addValue(9)に電話する場合。これは数字9を結果に加える関数を返します。resultです。関数addValueを呼び出して、結果に実際に数字を(addValue(digit)())追加することができます。しかし、addEventListenerは評価結果を取得しません。それは後でボタンがクリックされたときに呼び出す機能を取ります。

関連する問題