call,apply,bind

我们在使用一个对象时,其中有一个需要的方法这个对象上没有,这个时候我们当然可以在这个对象上新增这个方法,但是如果我们只是偶尔使用一次,那不是麻烦且作用不大吗?这时候我们自然而然的会想到可不可以找一个有这个方法的对象,然后把这个方法接过来用用呢?还真有这种方法!我们把别人家的方法借过来用,用的时候把人家方法中的this指向自己,用完之后再还给人家不就行了!call()apply()bind()方法 它们三者就是来实现这种想法的,它们都是Function.prototype下的方法,都可以改变this指向。

三者的使用

call()

  • 被借用者.call(借用者, a, b, c...)
    • 参数一:this要指向的地方;
    • 剩余参数:作为参数依次传入被借用的方法里;

apply()

  • 被借用者.apply(借用者,[a, b, c...])
    • 参数一:this要指向的地方;
    • 参数二:是一个数组,里面的元素作为参数依次传入被借用的方法里;
  • call()apply()只在使用方法上不一样,使用call()时,我们拿到剩余参数,把参数一个一个的传进去;而使用apply()时,我们把剩余的参数放到一个数组里,然后把这个数组作为第二个参数传进去;

bind()

  • 被借用者.bind(借用者,)
    • 参数一:this要指向的地方;
    • 剩余参数:拼接在调用返回函数所传参数之前,多余参数不起作用;
  • bind()call()apply()不太一样,bind()本身是个方法,调用bind()方法的是个方法,它的返回值也是个方法,这就使得通过bind()来借用别人方法的方法可以不直接使用借到的方法,它可以把返回的方法赋值给其他变量,并且调用完不可直接删除,方便下次调用。

三者的实现

call()

Function.prototype.rewriteCall = function(context) {

  //传入参数的话,就把被借的那个方法的this指向context,若context为非真值则指向window(js的顶层对象)

  context = context || window

  //在借用别人方法的对象上新添加一个方法(fn),并把调用call方法的函数(被借的那个)的this指向这个新添加的方法上,那么调用这个新加的方法(fn)时就可以用到被借的方法中的内容;

  context.fn = this

  //第一个参数是要借用别人方法的对象,所以把它去掉,拿到剩余参数

  const args = [...argumrnts].slice(1)

  //把剩余参数传入我们新加的方法(fn)中,调用这个方法,若有返回值,则接一下

  const result = context.fn(...args)

  //函数的目的是借用别家的函数,所以用完之后要及时删除哦(试想一下,每次借一个函数都要新增一个方法,并且只是特定情况需要,就很没必要)

  delete context.fn

  //如果有返回值,记得把返回值return

  return result

}

apply()

Function.prototype.rewriteApply = function(context) {

  context = context || window

  context.fn = this

  let result

  //这里的判断,如果arguments[1]存在,说明有第二个参数(并且为数组),那我们要把这个参数展开来传入方法中。

  if(arguments[1]) {

    result = context.fn(...arguments[1])

  }else{

    result = context.fn()

  }

  delete context.fn

  return result

}

bind()


Function.prototype.rewriteBind = function(context) {

  if(typeof this !== 'function') {

    throw new TypeError('Error')

  }

  //和实现apply与call那样,给context添加一个方法

  context.fn = this

  const args = [...arguments].slice(1)

   //返回一个绑定this的函数

  return function F() {

    //判断是否为一个函数

    if(this instanceof F) {

      return context.fn(...args, ...arguments)

    }

    return context.fn.apply(context, args.concat(...arguments))

  }

}
posted @   Rain1112022  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示