高阶函数
如果一个函数符合下面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接收的必须是一个函数,将函数柯里化可以有效解决这个问题。