bind,call,apply的用法,区别,手写

81 阅读1分钟
三者的用法

三者都是用来改变函数/方法的this指向的(改变执行上下文)

let obj = {name:"heihei"};
function Test(name){
    this.name = name;
}       
Test.prototype.sayName =  function(){
     	console.log(this.name);
     }
let t1 = new Test('cj');
t1.sayName(); //cj

//call,apply,bind函数的使用
t1.sayName.call(obj); //heihei
t1.sayName.apply(obj);//heihei

let mybind = t1.sayName.bind(obj); //bind函数不会立即执行,而是返回一个函数
mybind();//sayName

区别
  1. call和apply是调用就立即执行的,bind是复制一个新函数/方法,改变this指向后将其返回,返回的新函数/方法调用的时候才执行。
  2. apply接收两个参数,第一个是this要指向的对象,第二个是数组,里面放的是接受的参数。call和bind接收多个参数,第一个参数是this要指向的对象,后面的参数就是所需要的参数。
手写
//Apply函数书写
Function.prototype.myApply=function(obj,argsArr){
  let fn = this
  if(typeof fn !== functiton){
    throw new TypeError("not a function")
  }
  let thisArgs = (obj && obj instanceof Object) ? obj : window
  thisArgs.fn = fn
  let arr = [...argsArr] || []
  let res = thisArgs.fn(...arr)
  delete thisArgs.fn
  return res
}

//call函数手写
Function.prototype.myCall=function(obj,...args){
  let fn = this
  if(typeof fn !== functiton){
    throw new TypeError("not a function")
  }
  let thisArgs = (obj && obj instanceof Object) ? obj : window
  thisArgs.fn = fn
  let res = thisArgs.fn(...args)
  delete thisArgs.fn
  return res
}

//bind手写
Function.prototype.myBind=function(obj,...args){
  let fn = this
  if(typeof fn !== functiton){
    throw new TypeError("not a function")
  }
  let thisArgs = (obj && obj instanceof Object) ? obj : window
  return function(...args1){
    thisArgs.fn = fn
    let res = thisArgs.fn(...args1,...args)
    delete thisArgs.fn
    return res
  }
}