Function.prototype.myCall = function (context) {
if (typeof this !== 'function') {
console.error('只有函数上才有call方法');
return;
}
context = context ? Object.create(context) : window;
const args = Array.prototype.slice.call(arguments, 1);
const res = context.fn = this;
context.fn(...args);
delete context.fn;
return res;
}
Function.prototype.myApply = function (context) {
if (typeof this !== 'function') {
console.error('只有函数上有apply方法');
return;
}
context = context ? Object.create(context) : window;
context.fn = this;
const res = context.fn(...arguments[1]);
delete context.fn;
return res;
}
Function.prototype.myBind = function (context, ...args) {
if (typeof this !== 'function') {
console.error('只有函数上有apply方法');
return;
}
context = context ? Object.create(context) : window;
const self = this;
const returnFunc = function() {
self.apply(this instanceof returnFunc ? this : context, [...args, ...arguments])
}
return returnFunc;
}
function _new (fn, ...args) {
const obj = Object.create(fn.prototype);
const res = fn.apply(obj, [...args]);
return res instanceof Object ? res : obj;
}
function curry(fn, ...args) {
const length = fn.length;
if (args.length >= length) {
return fn.apply(this, [...args]);
} else {
return function(...nextArgs) {
return curry.apply(this, [fn, ...args, ...nextArgs])
}
}
}
const compose = function(...funcs) {
if (funcs.length === 0) {
return (arg) => arg;
} else if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
function sayHello(param1, param2, param3) {
console.log(this.name, param1, param2);
}
const thisObj = {
name: 'zaoren'
}
console.log('call test:------------------------------------------');
sayHello.call(thisObj, 'day', 'day up');
console.log('apply test:------------------------------------------');
sayHello.myApply(thisObj, ['day', 'day up']);
console.log('bind test:------------------------------------------');
const testBind1 = sayHello.myBind(thisObj, 'day')('day up');
console.log('bind 构建函数 new test:--------------------------------');
const bindCurry = sayHello.myBind(thisObj, 'day');
const testBind2 = new bindCurry('day up');
function Student(name) {
this.name = `${name}, day day up`;
}
console.log('new test:------------------------------------------');
const student = _new(Student, 'zaoren');
console.log('student', student.name);
console.log('curry test:------------------------------------------');
var fn = curry(function(a, b, c) {
return `${a} ${b} ${c}`;
});
console.log( fn("zaoren", "day", "dayup"));
console.log( fn("zaoren", "day")("dayup"));
console.log( fn("zaoren")("day")("dayup"));
console.log( fn("zaoren")("day", "dayup"));
console.log('compose test:------------------------------------------');
const dispatch1 = function(str) {
return str + ' day'
}
const dispatch2 = function(str) {
return str + ' dayup'
}
const dispatch3 = function(str) {
return str + '!'
}
const composedFunc = compose(dispatch3,dispatch2, dispatch1);
console.log('compose res', composedFunc('zaoren'));
console