/* call 第一个参数改变调用函数this的指向,第2-n个参数向调用的函数传参
模拟call:调用call的必须是一个函数 不是函数 return
当调用call而不穿this时,被调用函数中的this也被重定向了,指向window
将调用函数赋值给传进去的context
然后在context中调用这个函数
最后保证context前后统一,删除fn
*/
const obj={
a:1
}
Function.prototype.mycall=function(context,...arg){
if(typeof(this)!=='function') return;
context=context || window;
const key=Symbol();
context[key]=this
context[key](...arg)
delete context[key];
}
function callTest(...dos){
console.log(this) //obj
}
callTest.mycall(obj)
/*
apply和call的用法基本一样 但有一点不同的是
使用apply向调用函数传参 参数类型一定要是数组类型
否则报错
*/
Function.prototype.myapply=function(context,arg){
context=context || window;
if(arg){
if(Object.prototype.toString.call(arg)!=='[object Array]'){
throw new Error('')
}
}
const key=Symbol();
context[key]=this
context[key](arg)
delete context.fn;
}
function applyTest(arg){
console.log(this) //obj
}
applyTest.myapply(obj,[1,2,3])
/*
bind与apply call最大的区别就是
被调用函数与bind绑定了之后不会被立即调用
而是返回了一个代理函数 当代理函数被调用时,bind才会执行
传的参数也是依次传参
*/
Function.prototype.mybind=function(){
const self=this
const context=[].shift.call(arguments) || window;
const agr=[].slice.call(arguments)
return function(){
return self.apply(context,[].concat.call(agr,[].slice.call(arguments)))
}
}
function bindTest(){
console.log(this)
}
bindTest.mybind(null,1,2,3)() //this指向window
bindTest.mybind(obj,1,2,3)() //this指向obj