javascript - 关闭-换硬币

标签 javascript closures

我想理解闭包概念,所以练习这个练习。然而我完全迷失和困惑。任务是找到满足总数所需的最少硬币。因此,我想要一个数组,价格为 7.60 英镑 分辨率 = [2, 2, 2, 1, 0.5, 0.1]

这是我到目前为止所拥有的:

function sortCoins (money, coins){
  res = [];

if(money % coins[0] !== 0){
  return  function(){
    do{
      money = money - coins[0];
      res.push(coins[0]);
    }
    while(coins[0]<= money);
    coins.shift();
  };
  // coins.shift();
} else {
  do{
      money = money - coins[0];
      res.push(coins[0]);
    }
    while(money !== 0 );
}

return res;


}

sortCoins (17, [5, 2, 1, 0.5, 0.25, 0.1  ])();

我非常感谢任何帮助、解释和建议,以更好地理解闭包,阅读和练习哪些内容。 我看到了类似硬币问题的解决方案,但我不想只使用它,我需要了解我在代码中做错了什么。

最佳答案

您在 sortCoins 中返回一个函数,这有点奇怪,因为您也在 sortCoins 中返回 res

此外,您还没有定义 res 变量,因为您没有在其前面添加 var,因此访问未定义的全局变量也是如此。

最后一点,作为提示,请保持缩进干净。你有一堆乱七八糟的空格,这使得代码块乍一看很难理解。

简而言之,问题在于返回。让我解决这个问题:

功能:

function sortCoins(money, coins){
    var res = [];
    // Use an index instead of modifying the array. Keep the parameters immutable when possible.
    var current = 0;
    do {
        money = money - coins[current];
        res.push(coins[current]);
        while (money < coins[current]) {
            current++;
        }
    } while(money > 0);
    return res;
}

// console.log it, to see in the F12 console tab
console.log(sortCoins(17, [5, 2, 1, 0.5, 0.25, 0.1]));

关闭它:

我们将创建一组硬币,如下所示:

function sortCoins(coins) {
    // Notice that this function returns another function
    return function(money) {
        var res = [];
        // Use an index instead of modifying the array. Keep the parameters immutable when possible.
        var current = 0;
        do {
            money = money - coins[current];
            res.push(coins[current]);
            while (money < coins[current]) {
                current++;
            }
        } while(money > 0);
        return res;
    };
}

var myCoins = sortCoins([5, 2, 1, 0.5, 0.25, 0.1]);
myCoins(17);

var myCoins_small = sortCoins([0.5, 0.25, 0.1]);
myCoins_small(17);

myCoins(12);
myCoins_small(12);

看一下 sortCoins 函数的内容。通过正确的缩进,很容易看出它返回一个函数。不查看返回函数的内容,您可以看到这是它唯一的返回:

function sortCoins(coins) {
    // Notice that this function returns another function
    return function(money) {
        [...]
    };
}

因此,如果您调用 sortCoins([5, 2, 1, 0.5, 0.25, 0.1]) ,它将返回一个函数,其中 coins 参数设置为[5,2,1,0.5,0.25,0.1]

var myCoins = sortCoins([5, 2, 1, 0.5, 0.25, 0.1]);

现在您有一个变量 myCoins,它是一个函数,其 coins 参数设置为 [5, 2, 1, 0.5, 0.25, 0.1]。换句话说,就像有这段代码:

var coins = [5, 2, 1, 0.5, 0.25, 0.1];
function myCoins(money) {
    var res = [];
    // Use an index instead of modifying the array. Keep the parameters immutable when possible.
    var current = 0;
    do {
        money = money - coins[current];
        res.push(coins[current]);
        while (money < coins[current]) {
            current++;
        }
    } while(money > 0);
    return res;
};

如果您在最后一段代码中调用 myCoins(17); 会发生什么?如果仔细观察,它会访问 coins 变量,因此如果将 coins 变量更改为 [0.5, 0.25, 0.1],您将收到不同的输出。

如何更改?回到第一个 sortCoins(coins) 函数,就像使用另一个 coins 属性调用它一样简单:

var myCoins_small = sortCoins([0.5, 0.25, 0.1]);

现在,myCoins_smallcoins 属性设置为另一个不同的数组,并返回另一个函数。现在您有 2 个函数,myCoinsmyCoins_small,每个函数都在其自己的上下文中运行,并且设置了 2 个不同的 coins 属性。

简而言之。 JS 中的闭包受到函数的限制。当您告诉代码对变量执行某些操作时,它将查看当前上下文(这是自己的函数)。如果没有找到变量,就会上一层(也就是说,会在父函数上查找)并在那里查找,如果在那里没有找到它,就会上一层,依此类推,直到达到所谓的“全局范围”(换句话说,第一行代码运行的主要级别)。

在这里你可以更容易地看到它:

var mainlevel = 0; // This variable is declared in the global scope, so exists in ALL the functions

function level1() {
    var level1variable = 1; // This variable is declared inside level1 function, so exists in ALL the level1 function and its descendants

    function level2() {
        var level2variable = 2; // This variable is declared inside level2 function, so exists in ALL the level2 function and its descendants

        // level2 has access to its own variables and the one in his parents
        console.log(level2variable, level1variable, mainlevel);
    }

    // If I say level1 to access level2variable, it will return error as cannot access it
    console.log(level2variable); 

    // But it can actually access his own variables and the parent ones
    console.log(level1variable, mainlevel); 
}

有了这个,并且知道 JS 保留返回函数的上下文,您就可以做一些很棒的事情,如 currying (这是我们用第一个 sortCoins(coins) 函数制作的东西)。

如果您有点迷失,请注意

function pepe(arg) {
    return arg * 2;
}

相同
var pepe = function(arg) {
    return arg * 2;
};

两者都可以通过 pepe(2) 调用,返回相同的输出。它们有细微的差别,但不会详细介绍,以免让您的头脑更加困惑。

关于javascript - 关闭-换硬币,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45323953/

相关文章:

javascript - Jssor slider 不会自动启动

javascript - HTML - 使用按钮在新窗口中打开本地 PDF

rust - 将 '&self' 方法中的闭包添加到结构中的属性

php - Closure::bindTo 是如何工作的?

javascript - 对于 Ajax 请求,我的函数应该通过 .fail() 回调返回什么?

javascript - 我如何更改我当前的代码以将我的 div 设置为最小高度而不是高度 jQuery

javascript - 将 ionic 应用程序中的域列入白名单

javascript - javascript闭包函数的使用

javascript - 哪个函数是真正的闭包?

javascript - 如何在 JavaScript 中为此函数实现闭包?