Function.prototype.myCall = function(context) {
if (Object.prototype.toString.call(this).slice(8, -1) !== 'Function') {
console.error('只有函数才能调用call函数');
return;
}
context = Object.create(context) || window;
const args = Array.from(arguments).slice(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') {
console.error('只有函数类型才有apply属性');
return;
}
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') {
console.error('只有函数类型有myBind属性');
return;
}
const args = Array.from(arguments).slice(1);
const self = this;
const returnFn = function() {
const extArgs = Array.from(arguments);
self.apply(this instanceof returnFn ? this : context, [...args, ...extArgs]);
}
const fn = function() {};
fn.prototype = this.prototype;
returnFn.prototype = new fn();
return returnFn;
}
function _new(fn, ...args) {
const obj = Object.create(fn.prototype);
const ret = fn.apply(obj, args);
return ret instanceof Object ? ret : obj;
}
function sayHello(param1, param2, param3) {
console.log(this.name, param1, param2);
}
const thisObj = {
name: 'zaoren'
}
sayHello.myCall(thisObj, 'day', 'day up');
sayHello.myApply(thisObj, ['day', 'day up']);
const wSayHello = sayHello.myBind(thisObj, 'day')('day up');
function Student(age) {
this.name = 'zaoren';
this.age = age;
return this;
}
const student = _new(Student, '18');
console.log('student', student);
console