/ JavaScript  

柯里化&&闭包

柯里化

闭包实现

multi(2)(3)(4)=24

1
2
3
4
5
6
7
function multi(a) {
return function(b) {
return function(c) {
return a * b * c;
};
};
}

函数柯里化

函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数且返回结果的新函数的技术。

函数柯里化的主要作用和特点就是参数复用、提前返回和延迟执行。

普通版

把固定的函数变成柯里化。如果传入的参数个数小于 fn 所需要的形参个数,就继续执行 curry 函数接收参数,如果参数达到 fn 所需要的形参个数,就执行柯里化了的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function curry(fn, args) {
var length = fn.length;
var args = args || [];
return function() {
newArgs = args.concat(Array.prototype.slice.call(arguments));
if (newArgs.length < length) {
return curry.call(this, fn, newArgs);
} else {
return fn.apply(this, newArgs);
}
};
}
function multiFn(a, b, c) {
return a * b * c;
}
var multi = curry(multiFn);
multi(2)(3)(4);
multi(2, 3, 4);
multi(2)(3, 4);
multi(2, 3)(4);

优化版

不需要事先知道函数形参个数。可以任意参数个数调用。(重写 valueOf 函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
function multi() {
var args = Array.prototype.slice.call(arguments);
var fn = function() {
var newArgs = args.concat(Array.prototype.slice.call(arguments));
return multi.apply(this, newArgs);
};
fn.valueOf = function() {
return args.reduce(function(a, b) {
return a * b;
});
};
return fn;
}

img

闭包

1
2
3
4
5
6
7
var func = [];
for (var i = 0; i < 10; i++) {
func[i] = function() {
return i;
};
}
console.log(func[6]); //10

改成

1
2
3
4
5
6
7
8
9
10
var func = [];

for (var i = 0; i < 10; i++) {
func[i] = (function() {
return (function() {
return i;
})();
})();
}
console.log(func[6]); //6