[英]Function that returns a function (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;
}
}
};
在此示例中,我假設該網頁是一個計算器,類似於:
|---------------|
| |
|---------------|
| 1 | 2 | 3 | * |
|---|---|---|---|
| 4 | 5 | 6 | / |
|---|---|---|---|
| 7 | 8 | 9 | = |
|---------------|
在這種情況下,按鈕buttons[i]
是計算器按鈕之一; | 1 |
, | 5 |
| 5 |
等等。按鈕的實際編號是它的索引,因此buttons[2]
將為| 2 |
| 2 |
, buttons[7]
為| 7 |
| 7 |
等等。我猜還有其他值,例如buttons[0]
和buttons[10]
是操作員按鈕( | = |
, | * |
, | / |
)。
現在,當用戶單擊這些按鈕之一時,按鈕上的字符(即按鈕的innerHtml
)被添加到計算器的result
(通過將其添加到結果的innerHTML
),這只是該操作的顯示。 因此,如果我單擊| 3 |
| 3 |
然后| * |
| * |
然后| 5 |
| 5 |
,計算器看起來像
|---------------|
| 3*5 |
|---------------|
| 1 | 2 | 3 | * |
|---|---|---|---|
| 4 | 5 | 6 | / |
|---|---|---|---|
| 7 | 8 | 9 | = |
|---------------|
這是addEventListener
起作用的地方。 當您調用element.addEventListener("click", func)
,只要單擊element
,就會調用func
。 因此,要在單擊結果時將按鈕添加到結果中,可以執行以下操作:
buttons[i].addEventListener("click", addButtonValueToResult);
其中, addButtonValueToResult
是將按鈕的值添加到結果中的函數。
問題在於,不同的按鈕具有不同的值,因此像這樣的一個功能將不適用於所有按鈕。 因此, addButtonValueToResult
不能是一個簡單的函數。 每個按鈕都需要自己的功能。 一種這樣的解決方案是放棄for循環,然后執行以下操作:
buttons[1].addEventListener("click", add1ToResult);
buttons[2].addEventListener("click", add2ToResult);
buttons[1].addEventListener("click", add3ToResult);
...
然后具有以下功能:
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
不會獲得評估結果。 它帶有一個函數,稍后單擊該按鈕時將調用該函數。
一種方法是:
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閉包的更多信息。
因此,根據我在下面與Marty收集的內容(並重新閱讀您的問題),您想知道為什么需要返回一個函數(或類似函數)。 addEventListener
需要一個在單擊事件發生時調用的函數。 因為您不是直接調用該函數(也就是運行它),所以對於傳遞什么參數沒有任何發言權。 在這種情況下,唯一要傳遞的參數是事件對象,其中包含有關單擊發生位置,與之相關的元素等信息,您必須將其包裝在另一個函數中才能傳遞值。 i
到您必須運行的最終功能。 (上面已經顯示了另一個示例)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.