Function.prototype.apply
apply接受2个参数, 第1个指定了函数体内this对象的指向, 第2个参数为一个数组或者Array like的集合.
apply方法吧这个集合中的元素作为参数传递给被调用的函数.
var func = function(a, b, c) { console.log([a,b,c]); // [1,2,3] } func.apply(null, [1,2,3])
Function.prototype.call
包装apply. 如果知道函数接受多少个参数, 想一目了然的比殴打形参和实参的对应关系.
当使用call/apply时候. 如果第1个参数惨null, this默认指向window
严格模式下为null
var func = function(a, b, c) { "use strict"; console.log(this === null); // true } func.apply(null, [1,2,3])
* 实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
function callIt(fn) { return fn.apply(this, [].slice.call(arguments, 1)); } // test var fn = function(a, b, c) { return a+b+c; } callIt(fn, 1, 2, 3); // 6
* 实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) { var args = [].slice.call(arguments, 1); return function() { // [].slice.call(arguments) => 把arguments伪数组转换为数组 return fn.apply(this, args.concat([].slice.call(arguments))) } }
* 函数curry
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
input: var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
output: 6
function curryIt(fn) { // var args = [].slice.call(arguments, 1) // return fn.apply(this, args); return function(a) { return function(b) { return function(c) { return fn.call(this, a, b, c); } } } } var fn = function (a, b, c) { return a + b + c; }; // console.log( curryIt(fn, 1, 2, 3) ); console.log( curryIt(fn)(1)(2)(3) );