我想了解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 ])();
我真的很感激任何帮助,解释和建议,阅读和练习更好地理解Closure。 我看到了类似Coins问题的解决方案,但我不想只使用它,我需要了解我在代码中做错了什么。
答案 0 :(得分:2)
您在sortCoins
内返回一个函数,这有点奇怪,因为您还在res
内返回sortCoins
。
此外,您尚未定义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_small
将coins
属性设置为另一个不同的数组并返回另一个函数。现在,您有两个函数myCoins
和myCoins_small
,每个函数都在其自己的上下文中运行,该函数设置了2个不同的coins
属性。
简而言之。 JS中的闭包受功能限制。当您告诉代码对变量执行某些操作时,它将查看当前上下文(这是自己的函数)。如果找不到变量,将上升一级(也就是说,将查看父函数)并查看那里,如果在那里找不到它,将会上升到另一个级别,并且等等,直到达到所谓的全球范围&#34; (换句话说,第一行代码运行的主要级别。)
在这里你可以更容易地看到它:
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)
调用两者来返回相同的输出。他们有微小的差异,但不会进入细节,不会弄得更多。