柯理化函数思想
柯理化函数思想利用的是闭包的机制,把一些信息预先存储下来,是一种预处理的思想。
function fn(...arg1){
return function anonymous(...arg2){
let args = arg1.concat(arg2);
return args.reduce((n,item) =>n+item);
}
}
let res =fn(1,2)(3);
console.log(res);
//=> 6
数组reduce方法
reduce方法有两个参数:
- 回调函数,回调函数里面有两个参数:
- pre:上一项
- next:下一项
- 第二个参数可以修改第一次的pre
上一次回调函数的return的值作为下一次的回调函数的n,而下一次的item是数组的下一项
下面是两种传参的情况
- 没有传第二个参数的情况:只传了第一个参数,是一个回调函数
let ary =[10,20,30,40,50,60];
let res =ary.reduce((n,item)=>{
console.log(n,item);
return n+item;
});
console.log(res);
//=>10 20
30 30
60 40
100 50
150 60
210
解析: 第一次触发回调函数执行的n是数组第一项,item是数组第二项;第二次执行时,n是第一次执行的return的值,本代码中是数组第一项加数组第二项的结果,而item则是数组的第三项;第x次执行时,n是第x-1次回调函数的返回结果,item是数组的第x+1项。
- 传第二个参数的情况:如果传了第二个参数,则第一次执行时,n是第二个参数,而item是数组的第一项
let ary =[10,20,30,40,50,60];
let res =ary.reduce((n,item)=>{
console.log(n,item);
return n+item;
},0);
console.log(res);
//=> 0 10
10 20
30 30
60 40
100 50
150 60
210
箭头函数
箭头函数的特点
首先,箭头函数省略了function关键词
let res = function(x,y){}
let res = (x,y) => {}
另外,如果只有一个形参,则可以把小括号省略
let res = x =>{}
还有,如果大括号里面只有 return 一个值,大括号也可以省略了
let res = function (x,y){
return x+y;
}
let res = (x,y) => x+y ;
如果只有一个参数,还只有return一个值的话,就非常的方便了
let res = x => ++x;
console.log(res(1));
//=> 2
注意: 不过箭头函数中没有this,它里面的this是上级作用域中的this
箭头函数的this指向问题
箭头函数本身不创建this;
也可以说箭头函数本身没有this,但是在它声明时可以捕获别人的this供自己使用。
特别说明: this一旦被捕获,以后将不再变化。
箭头函数中的this是在它声明时捕获它所处作用域中的this。
即使用 call、apply或bind 也无法改变箭头函数this的指向
箭头函数与普通函数的区别
- 外形不同:箭头函数使用箭头定义,普通函数中没有。
- 箭头函数全都是匿名函数:普通函数可以有匿名函数,也可以有具名函数。
- 箭头函数不能用于构造函数:普通函数可以用于构造函数,以此创建对象实例。
- 箭头函数中this的指向不同。这一点在上文和我的其他博客中都有专门的说明,此处不做赘述
- 箭头函数不具有arguments对象:每一个普通函数调用后都具有一个arguments对象,用来存储实际传递的参数。但是箭头函数并没有此对象。
- 其他区别:
(1).箭头函数不能Generator函数。
(2).箭头函数不具有prototype原型对象。
(3).箭头函数不具有super。
(4).箭头函数不具有new.target。
compose思想
compose:组合函数,把嵌套调用的多层函数实现扁平化
const fn1 = x => x+10;
const fn2 = x => x-10;
const fn3 = x => x*10;
const fn4 = x => x/10;
let res = fn4(fn3(fn2(fn1(20))));
console.log(res);
使用 compose 思想,手写一个compose函数,实现上述的函数调用,并且让函数执行顺序更加清晰,便于理解
const fn1 = x => x+10;
const fn2 = x => x-10;
const fn3 = x => x*10;
const fn4 = x => x/10;
function compose(...arg1){
//arg1中存储按顺序执行的函数(数组) => [fn1,fn2,fn3,fn4]
return function(...arg2){
//arg2存储第一个函数执行需要传递的实参信息(数组) =>[20]
//判断传进来的函数构成的数组arg1的长度
if(arg1.length === 0){return arg2};
if(arg1.length === 1){return arg1[0](...arg2)};
return arg1.reduce(function(pre,next){
// 第一次的pre的值:第一个函数执行的实参,next是第一个函数
//第二次的pre的值:上一次next执行的返回值,作为实参传递给下一个函数执行
return Array.isArray(pre)?next(...pre):next(pre);
},arg2);
};
}
let res = compose(fn1,fn2,fn3,fn4)(20);
console.log(res);
//=> 20
这样一来,执行compose函数时,传参的顺序就是函数执行的顺序。