一、相关回顾
1、.length的用法
函数中我们可以使用函数名.length来查询函数的参数的个数,这个属性的值永远不会改变,并且总是匹配函数声明参数的数量。
1 | function test(a,b,c){ |
2.函数的arguments
在函数域内都有一个arguments
变量来访问传递给函数的所有参数。这是一个类数组,类数组有数组的length用法,并且可以用下标的索引方式来访问每个元素。和数组不同的是,他的类型是Object,并且不能调用数组的类似pop()之类的API,也不能是使用for in语句来实现对类数组的遍历。类数组转化为数组的方式是Array.prototype.slice.call(arguments),当然可以简写为[].slice.call(arguments)
在ES语法中,我们也可以使用spread operator(扩展操作) / rest parameters(剩余参数) 来访问参数:
1 | function howMany(...args) { |
二、 Currying(柯里化) 函数
Currying(柯里化) 函数是加上就是把接受 N 个参数的函数转换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果。并且我们也希望可以用一个或多个参数来调用它,然后它将部分应用;直到它收到最后一个参数(基于原始函数的参数数量),此时它将返回使用所有参数调用原始函数的计算值。 于是我们可以做下面的写法:
1 | function curry(fn){ |
每次调用的时候,我们都会获取调用时候的参数并且会结合之前的参数进行判断,当前已经获取的参数是否已经大于声明的函数的参数,如果大于等于就会执行被声明的函数,如果不大于就会返回一个函数继续重复接受参数并执行。
但是上面的写法中,我们在每次设置apply函数的环境的时候都是null,这样在一些情况下会出问题。
1 | function curry(fn){ |
发现执行的结果中,name变成了undefined,这就是因为我们的this在调用的时候赋了null导致的。这时候我们就需要指定该函数执行的上下文this,在我们第一次调用的时候我们就利用context纪录每次执行的环境this:
1 | function curry(fn){ |