call,apply,bind的用途

call和apply的区别

在前端日常工作中,this的指向是一个飘忽不定但是又要掌握的知识。

在ECMAscript3中,给Fucntion.protptype定义了call和apply方法,用来改变this的指向,都接收两个参数,第一个参数都为函数体内this对象的指向,call是从第二个参数开始,每个参数给以此传入,如Fucntion.protptype.call(obj,a,b,c),apply的第二个参数为一个数组或者类数组,apply会将数组或类数组元素作为参数传递给被调用的函数,如Fucntion.protptype.apply(obj,[a,b,c])。

call和apply的用途

1.改变this指向

在开发中,this指向不经意就改变,不符合我们的预期,比如:
 

document.getElementById('mydiv').onclick = function () {
  console.log(this.id) //输出mydiv
  var fun = function () {
    console.log(this.id) //输出undefined,不符合我们的预期
  }
  fun()
}

我们可以用call或者apply来来改变函数内的this,让其指向mydiv:
 

document.getElementById('mydiv').onclick = function () {
  console.log(this.id) //输出mydiv
  var fun = function () {
    console.log(this.id) //输出mydiv1
  }
  fun.call(this)
}

2.借用其他对象的方法要

比如我们要找数组的最大值,想要调用Math.max(),但是此方法需要逐个输入参数,我们就可以call或者apply来实现借用:

Math.max.apply(null,[1,2,5,8,2]) //输出8

在函数中,我们会经常使用函数参数列表arguments,他是一个类数组,但是我们经常会想把他按照数组使用,我们也可以call或者apply来实现借用:

function arguToArr () {
  1.
  [].push.call(arguments,4,5)
  console.log(arguments) // [1,2,3,4,5]
  2. 
  let arr = [].slice.call(arguments)
  console.log(arr) // [1,2,3]
}
arguToArr(1,2,3)

所以当我我们想把arguments转为数组时,可以借用Array.prototype.slice方法,当我们想截取arguments第一个参数,可以借用Array.prototype.shift方法等等...

3.实现bind,现在实现了Fucntion.protptype.bind(obj,a,b,c),但是我们也可以自己简单模拟一下:

Function.prototype.myBInd = function (obj) {
  let self = this
  return function () {
    return self.apply(obj,arguments)
  }
}
let obj = {name:'zs'}
let func = function () {
  console.log(this.name) //输出zs
}.myBInd(obj)
func() 

实际上bind要复杂一点:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          // 当通过new方法调用时,this就是fNOP的一个实例  
          return fToBind.apply(this instanceof fNOP
                                 ? this
                                 : oThis || this,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

bind和call、apply的区别是bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值