Function.prototype.myCall = function(context) {
if (Object.prototype.toString.call(this).slice(8, -1) !== 'Function') {
throw new Error('调用类型必须是Function类型!');
}
context = context ? Object.create(context) : window;
const args = Array.prototype.slice.call(arguments, 1);
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
}
Function.prototype.myApply = function (context) {
if (Object.prototype.toString.call(this).slice(8, -1) !== 'Function') {
throw new Error('调用apply的必须是函数类型')
}
context = context ? Object.create(context) : window;
const args = arguments[1];
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
}
Function.prototype.myBind = function (context) {
if (Object.prototype.toString.call(this).slice(8, -1) !== 'Function') {
throw new Error('调用的对象类型必须是 Function 类型');
}
const self = this;
context ? Object.create(context) : window;
const args = Array.prototype.slice.call(arguments, 1);
const returnFn = function () {
const argsAdd = Array.prototype.slice.call(arguments);
return self.apply(this instanceof returnFn ? this : context, [...args, ...argsAdd])
};
const fn = function () { };
fn.prototype = this.prototype;
returnFn.prototype = new fn();
return returnFn;
}
function _new(fn) {
const obj = Object.create(fn.prototype);
const res = fn.apply(obj, Array.prototype.slice.call(arguments, 1));
return res instanceof Object ? res : obj;
}
const sub_curry = (fn, ...args) => (...newArgs) => fn(...args, ...newArgs)
const curry = (fn, length = fn.length) => (...args) => {
if (args.length < length) {
return curry(sub_curry(fn, ...args), length - args.length)
} else {
return fn(...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