返回函数的函数(Javascript)

时间:2016-07-29 01:43:45

标签: javascript html

我正在查看一些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;
        }
    }
};

2 个答案:

答案 0 :(得分:1)

在此示例中,我假设网页是计算器,类似于:

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

在这种情况下,按钮buttons[i]是计算器按钮之一; | 1 || 5 |等。按钮的实际数量是其索引,因此buttons[2]| 2 |buttons[7]| 7 |我猜测其他值,例如buttons[0]buttons[10],是操作员按钮(| = || * || / |)。

现在,当用户点击其中一个按钮时,按钮上的字符(即按钮innerHtml)会添加到计算器result中(通过将其添加到结果&#39; s innerHTML),这只是操作的显示。因此,如果我点击| 3 |,然后| * |,然后点击| 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])并添加该按钮& #39;结果的值?

这确实是这个程序的作用: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没有取得评估结果;它需要一个函数,稍后单击按钮时它将调用它。

答案 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的值,您必须运行的最终函数。 (我已经在上面展示了另一个例子)。