call、apply和bind
call
Function.prototype.hyCall=function (thisArg,...arg) {
var fn = this //拿到被执行的函数foo,因为通过foo.hyCall()调用所以可以拿到hyCall的this是foo函数本身
// fn.call(thisArg) //简略方法 直接调用call
thisArg = (thisArg!==null&&thisArg!==undefined) ? Object(thisArg) : window // 将输入的参数封装为对象,当绑定目标为null或者undefined时,不进行绑定
thisArg.fn=fn //在传入对象中添加方法
let result = thisArg.fn(...arg) //调用将fn(foo)中的this绑定到thisArg上
delete thisArg.fn
return result
}
function foo (sum1,sum2) {
console.log('这是foo函数',this);
return sum1+sum2
}
foo()
foo.call()
foo.hyCall()
总结:先在函数的原型链上添加hyCall方法,再拿到foo函数(因为是通过foo.hycall,所以hycall内的this隐式绑定foo),再将hycall中的第一个形参包裹为对象,在这个对象中添加foo方法,使用thisArg.foo() 去调用foo从而使foo绑定到形参上
apply
Function.prototype.hyApply=function (thisArg,args) {
let fn = this
thisArg = (thisArg===null||thisArg===undefined) ? window : object(thisArg)
thisArg.fn = fn
args=args?args:[] //判断args是否有值传入
result= thisArg.fn(...args)
delete thisArg.fn
return result
}
function foo (sum1,sum2) {
console.log('这是foo的this:',this,);
return sum1+sum2
}
result = foo.hyApply('abc')
console.log(result);
bind
Function.prototype.hybind = function(thisArg, ...argArray) {
// 1.获取到真实需要调用的函数
var fn = this
// 2.绑定this
thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg): window
function proxyFn(...args) {
// 3.将函数放到thisArg中进行调用
thisArg.fn = fn
// 特殊: 对两个传入的参数进行合并
var finalArgs = [...argArray, ...args]
var result = thisArg.fn(...finalArgs)
delete thisArg.fn
// 4.返回结果
return result
}
return proxyFn
}