2017-07-26 91 views
0

我想了解Closure概念,因此练习此练习。但是我完全迷茫和困惑。任务是找到需要用来满足总数的最小硬币。结果是£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 ])(); 

我会很感激的任何帮助,说明和建议读什么书和实践,了解关闭更好。 我看到类似Coins问题的解决方案,但我不想只用它,我需要了解我在代码中做错了什么。

+0

你能解释一下你的代码中没有工作或应该改进的东西吗? – T30

+0

@ T30感谢您的回复。现在我的资源是不确定的,我想获得资源= [5,5,5,2],因为它是需要用来满足17的最小硬币。 – Polina

回答

2

您在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])); 

Closuring它:

我们要打造一个集币,这样的:

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]); 

现在​​有coins属性设置为另一个不同的阵列,并返回另一个函数。现在你有2个函数,myCoins和​​,每个函数在其自己的上下文中运行,其中有两个不同的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)返回相同的输出被调用。他们有微小的差异,但不打算进入细节不要把你的头更多。

+0

非常感谢您的解释和建议!但我注意到,如果我用sortCoins(11,[5,2,1,0.5,0.25,0.1])检查代码),结果将是错误的。而且它不再是关闭,这仍然是很好的练习,但我最好想理解在函数内返回函数的概念... – Polina

+0

@Polina更新了一个修复和详细的答案 –

+0

非常感谢你这只是最好的解释! – Polina