繁体   English   中英

返回函数的函数(Javascript)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM