Javascript 关闭-硬币的更换

Javascript 关闭-硬币的更换,javascript,closures,Javascript,Closures,我想了解闭包的概念,所以练习这个练习。然而,我完全迷茫了。任务是找到最少的硬币,以满足总需求。因此,对于7.60英镑,我希望有一个数组 res=[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]; re

我想了解闭包的概念,所以练习这个练习。然而,我完全迷茫了。任务是找到最少的硬币,以满足总需求。因此,对于7.60英镑,我希望有一个数组 res=[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  ])();
功能分类码(货币、硬币){
res=[];
如果(货币%coins[0]!==0){
返回函数(){
做{
货币=货币-硬币[0];
重推(硬币[0]);
}

而(coins[0]在
sortCoins
中返回函数,这有点奇怪,因为在
sortCoins
中也返回
res

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

最后一点,作为提示,保持缩进干净。你有一大堆空格,这使得代码块一眼就很难理解

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

职能: 因此,如果调用
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\u small
coins
属性设置为另一个不同的数组并返回另一个函数。现在您有了两个函数,
myCoins
myCoins\u small
,每个函数都在自己的上下文中运行,其中有两个不同的
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保留了返回函数的上下文,您可以做一些很棒的事情,例如(这是我们使用第一个
sortCoins(coins)
函数所做的事情)

如果你有点迷路,请注意

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

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

这两个函数都可以通过
pepe(2)
调用,返回相同的输出。它们有细微的区别,但不会进入细节,以免让你的头脑更混乱。

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

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

最后一点,作为提示,保持缩进干净。你有一大堆空格,这使得代码块一眼就很难理解

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

职能: 因此,如果调用
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\u small
coins
属性设置为另一个不同的数组并返回另一个函数。现在您有了两个函数,
myCoins
myCoins\u small
,每个函数都在自己的上下文中运行,其中有两个不同的
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保留了返回函数的上下文,您可以做一些很棒的事情,例如(这是我们使用第一个
sortCoins(coins)
函数所做的事情)

如果你有点迷路,请注意

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

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

这两个函数都可以通过
pepe(2)
调用,返回相同的输出。它们之间有一些细微的差异,但不会进入细节,以免让您的头脑更加混乱。

您能在代码中解释什么不起作用或应该改进吗?@T30谢谢您的回复。现在我的res没有定义,我想得到res=[5,5,2],因为这是满足17要求所需的最小硬币数。您能在代码中解释什么不起作用或应该改进吗?@T30谢谢您的回复。现在我的res未定义,我想得到res=[5,5,5,2],因为这是实现17的最少硬币数。非常感谢您的解释和建议!!但我注意到如果我用排序码(11、[5,2,1,0.5,0.25,0.1])检查代码结果将是错误的。而且它不再是闭包,这仍然是很好的实践,但我理想情况下希望理解在函数中返回函数的概念…@Polina更新了修复程序和详细的回答非常感谢这只是最好的解释!@Polina很高兴你喜欢它:-)非常感谢你的解释d推荐!!但是我注意到如果我用so检查代码