高阶函数

如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。

  • 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
  • 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
  • 常见的高阶函数有:Promise、setTimeout、arr.map()等等
函数柯里化

函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。

function sum(a){
   return function(b){
       return function(c){
           return a+b+c
       }
   }
}

如果还是不了解,先来看一道面试题

var add = function(x){
    var sum = 1;
    var tmp = function(x){
        sum = sum + x;
	return tmp;
    }
    tmp.toString = function(){
        return sum;
    }
    return tmp;
} 
// alert(add(1)(2)(3)) --> 6
// alert(add(100)(2)(3)) --> 6
// alert(add(1)(4)(5)) --> 10

我构建了一个简单的函数create1,并且有一个返回值,返回值是一个内部函数。

function create1(pro) {
	console.log("pro : " + pro);
	return function(obj1, obj2){
		console.log(obj1 + " -- " + obj2);
		return obj1 + obj2;
	}

函数构建完了,接下来进行调用:

//1.创建函数,实际compare接收了一个函数,因此可以继续调用
var compare=add (pro);
//2.调用函数
alert(compare(obj1,obj2));

//以上操作可简写为
alert(compare(pro)(obj1,obj2));

类似这种函数返回另一个函数的,我们第一次调用只是构建了一个外层函数体对象,只有有后续的调用,才能调用内层函数体,并且重复调用,只会重复内层函数体。

所以使用add(1)(2)(3)时相当于add()(2)(3)
先创建函数,构建一个外层函数整体对象,然后才是对内部函数的后续调用。

那么柯里化的函数实际应用场景是啥呢?
//html碎片
<input onChange={this.saveFormData('username')} type="text" name="username"/>
//js碎片
function saveFormData(name){
console.log(name)
}

这是一个简单的输入框事件,很明显我们希望输入框内容改变的时候出发函数。但是实际的效果是,浏览器首次加载的时候,事件自动执行,之后事件触发无反应。为什么呢?因为实际上在首次加载的时候saveFormData()调用并执行了函数方法,并返回了undefined。之后事件再被触发,执行的不是saveFormData函数,而是它的执行结果,所以无效。onChange接收的必须是一个函数,将函数柯里化可以有效解决这个问题。