call、apply、bind

80 阅读1分钟

1、目标对象

函数调用call、apply、bind方法,改变this指向

2、参数

.call(this指向,参数一个个传进去) .apply(this指向,参数组成的数组) .bind同.call用法,不同的是.bind返回的是函数

3、手写实现(详见下方代码) 调用call、apply、bind的是函数 执行函数并传参

Function.prototype.myCall=function(context){
  // 判断是否是函数调用的
  if(typeof this !== 'function'){
    throw new TypeError('Not a Function')
  }  

  // 初始化
  context=context||Window
  context.fn=this

  // 获取参数
  let args=Array.prototype.slice.call(arguments,1)

  // 调用函数
  let result=context.fn(...args)
  delete context.fn
  return result
}

Function.prototype.myApply=function(context){
  // 判断是否是函数调用的
  if(typeof this !== 'function'){
    throw new TypeError('Not a Function')
  }  

  // 初始化
  context=context||Window
  context.fn=this

  // 获取参数、调用函数
  let args=arguments[1]
  let result
  if(args){
    result=context.fn(...args)
  }else{
    result=context.fn()
  }
  delete context.fn
  return result
}

Function.prototype.myBind=function(context){
  console.log(context);
  console.log(Array.prototype.slice.call(arguments,1))
  // 判断是否是函数调用的
  if(typeof this !== 'function'){
    throw new TypeError('Not a Function')
  }  
  
  let self=this
  let args=Array.prototype.slice.call(arguments,1)

  return function (){
    self.call(context,...args)
  }
}



let obj={
  name:'张三',
  age:19,
  introduce(){
    console.log(arguments);
    console.log(this.name,this.age);
  }
}
// obj.introduce.myCall({name:'赵四',age:58},1,2,3)
// obj.introduce.myApply({name:'广坤',age:60},[1,2,3])
// obj.introduce.myBind({name:'老根',age:75},1,2,3)()

参考: www.runoob.com/w3cnote/js-…