1. 实现 Function.prototype.call
利用对象来调用方法以更改this指向为targetObj,调用方式:fnName.myCall (targetObj, arg1, arg2)
Function.prototype.myCall = function(targetObj = window, ...args) {
targetObj = new Object(targetObj);
let unique = 'key_' + Math.random();
// this指向调用这个myCall的方法,先把这个方法挂在targetObj上
targetObj[unique] = this;
// 再利用targetObj去调用这个方法以更改这个方法内部的this
let value = targetObj[unique](...args);
delete targetObj[unique];
return value;
}
2. 实现Function.prototype.bind
利用call或apply实现bind,调用方式:
newFn = fn.myBind(targetObj, arg1); // 支持预设参数
newFn(arg2)
;
Function.prototype.myBind = function(targetObj, ...args) {
// 调用myBind方法
let me = this;
return function(...innerArgs) {
return me.apply(targetObj, [...innerArgs, ...args]);
}
}
3. 实现pipe
multi(add(double(10)));
pipe返回一个函数,入参的函数每个都只接收一个入参,使用reduce实现,期望调用方式:
const fn = pipe(double, add, multi);
fn(10);
3.1 返回一个函数,在函数执行时reduce计算
function pipe(...arrFn) {
arrFn.forEach(fn=>{
if (typeof fn !== 'function') {
throw Error('expect function type');
}
}
);
return function(input) {
return arrFn.reduce((value,fn)=>{
return fn(value); // 上次执行的返回值作为下个函数的入参
}
, input); // 初始入参
}
;
}
3.2 利用reduce返回一个多层嵌套的函数
function pipe(...arrFn) {
arrFn.forEach(fn=>{
if (typeof fn !== 'function') {
throw Error('expect function type');
}
}
);
return arrFn.reduce((curFn,nextFn)=>{
return function() {
return nextFn(curFn(...arguments))
}
;
}
);
}
则pipe(add, double, multi);
执行返回的函数:
function() {
return multi((function() {
return double(add(...arguments))
})(...arguments))
}
网友评论