ES6语法:apply、call、compose函数、柯里化函数

参考文章

JavaScript 函数式编程 (ES6)

JavaScript柯里化

浅析 JavaScript 中的 函数 currying 柯里化

JS中的call()和apply()方法

apply与call的区别

区分apply与call只有一句话

foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments)==this.foo(arg1, arg2, arg3)

call,apply都是Function.prototype(prototypejavascript原型模式)的方法,是JavaScript引擎的内在实现,意味着每个Function对象实例,就是每个方法都有call,apply属性。

  • 相同点:作用完全相同
  • 不同点:传递参数不同,call传递参数序列,apply传递数组

this指代上下文对象,是指每个实例的this,代码在该this内执行。

当this为null时,指向全局对象,意思是调用一个函数时,不是一个具体对象的方法

arguments

使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们,意味着能以数组的形式,遍历函数的所有参数。

举个栗子

1
2
3
4
5
6
7
componentDidMount() {
this.testArguments(1,2,3,4,5,6);
}
testArguments(){
console.log("arguments",[].slice.call(arguments));
//arguments=[1,2,3,4,5,6]
}

柯里化curry

简单的说柯里化就是通过传入函数所需的部分参数,将一个函数分割为多个的一种技术。或者叫分部传参数求解。

柯里化允许你将一个函数转换为一些列函数,在经常调用一个相同参数的函数时,柯里化是很好的解决方案。

举个例子

1
2
3
4
5
6
7
8
9
function multiplier(x, y){
if(y===undefined){
return function(z){
return x * z;
}
}else{
return x*y;
}
}

利用闭包特性,函数会保留之前的传递的x

multiplier(3, 4) == multiplier (3)(4)

一个典型的柯里化函数

1
2
3
4
5
6
7
8
9
10
11
12
componentDidMount() {
...
var reciprocal = this.curry(divider,1);
reciprocal(2);
}
curry(func) {
var fixedArgs = [].slice.call(arguments,1);
return function() {
var args = fixedArgs.concat([].slice.call(arguments));
return func.apply(null, args);
};
}

执行reciprocal(2)相当于执行了this.curry(divider,1)(2),下面来重点讲解执行过程。

  1. this.curry执行[].slice.call(arguments,1),去掉传入的第一个参数即divider函数,返回fixedArgs,此时

fixedArgs=[1]

  1. 继续执行返回匿名函数,同时传入变量2
  2. 执行匿名函数,fixedArgs.concat([].slice.call(arguments)),将现在的变量arguments和之前的变量合并,返回args
  3. 使用apply执行第一个参数就是divider函数,参数是上一步拼接好的args函数
  4. 返回结果,完毕。