手写call
let obj = {name: '张三'};
let obj2 = {
name: '李四',
say: function(money1, money2){
console.log(this.name);
return money1 + money2;
}
}
obj2.say.call(obj, 100, 200)
Function.prototype.myCall = function(context){
context = !context ? window : context;
let fn = this;
let args = Array.prototype.slice.call(arguments, 1);
context.fn = fn;
let res = context.fn(...args);
delete context.fn;
return res;
}
obj2.say.myCall(obj, 200, 300)
手写apply
let obj = {name: '张三'};
let obj2 = {
name: '李四',
say: function(money1, money2){
console.log(this.name);
return money1 + money2;
}
}
obj2.say.apply(obj, [100, 200])
Function.prototype.myApply = function(context, arrParams){
context = !context ? window : context;
let fn = this;
context.fn = fn;
let res = context.fn(...arrParams);
delete context.fn;
return res;
}
obj2.say.myApply(obj, [100, 200])
手写bind
let obj = {name: '张三'};
let obj2 = {
name: '李四',
say: function(money1, money2){
console.log(this.name);
return money1 + money2;
}
}
let fn = obj2.say.bind(obj, 100);
fn(200)
new fn(200)
Function.prototype.myBind = function(context){
let fn = this;
context = !context ? window : context;
let args = Array.prototype.slice.call(arguments, 1);
context.fn = fn;
return function(){
let restArgs = Array.prototype.slice.call(arguments);
let allArgs = args.concat(restArgs);
let res = null;
if(new.target){
return _new(fn, ...allArgs);
}else{
res = context.fn(...allArgs);
}
return res;
}
}
function _new(fn){
console.log(arguments)
var obj = Object.create(fn.prototype);
var args = Array.prototype.slice.call(arguments, 1);
fn.call(obj, ...args);
return obj;
}
let fn2 = obj2.say.myBind(obj, 100);
fn2(200)
new fn2(200)