call和apply的区别和用法

call和apply的区别

ECAMScript3给Function的原型定义了两个方法,分别是Function.prototype.call和Function.prototype.apply,他们的作用一模一样,区别仅在于传参方式不同。

apply接收两个参数

第一个参数指定函数体内this对象的指向,第二个参数是数组或者类数组(例如arguments),是传入被调用函数的参数列表。

var func = function(a, b, c) {
  alert([a,b,c]) // 输出[1,2,3] 
}
func.apply(null,[1,2,3])

call参数数量不固定

与apply相同,第一个参数是指定函数体内this对象的指向,后面的是需要传入被调用函数的参数call实际上是包装在apply上的语法糖。如果我们需要明确的知道函数接收多少个参数,而且想一目了然的表达形参和实参的对应关系,可以用call。

var func = function(a, b, c) {
  alert([a,b,c]) // 输出[1,2,3] 
}
func.call(null,1,2,3)

调用apply和call时如果第一个参数为null,函数体内的this会指向默认的宿主对象。在浏览器中是window,在严格模式下还是null。

call和apply的用途

1.改变this指向

var obj1 = {
  name:'sven'
}
var obj2 = {
  name:'anne'
}

window.name = 'window'

var getName = function(){
  alert(this.name)
}

getName() // 输出 window
getName.call(obj1) // 输出 sven
getName.call(obj2) // 输出 anne

2.实现bind方法

简单版本

Function.prototype.bind = function(context) {
  var self = this; // 保存原函数
  return function() { // 返回一个新函数
    return self.apply(context, arguments); // 调用原函数并且将传入的context作为this传给原函数
  }
}


var obj = {
  name:'sven'
}

var func = function () {
  alert(this.name) // sven
}.bind(obj)

func()

复杂版本,使bind的时候可以预填写一些参数

Function.prototype.bind = function() {
  var self = this,// 保存原函数
      context = [].shift.call(arguments),// 取出context
      args = [].slice.call(arguments) // 将剩余的参数转换为数组
  return function() { // 返回一个新函数
    return self.apply(context, [].concat.call(args, [].slice.call(arguments))); // 调用原函数并且将传入的context作为this传给原函数
  }
}


var obj = {
  name:'sven'
}

var func = function (a,b,c,d) {
  alert(this.name) // sven
  alert([a,b,c,d]) // 1,2,3,4
}.bind(obj,1,2)

func(3,4)

3.借用其他对象的方法

1.借用构造函数,可以实现类似继承的效果

var A = function(name) {
  this.name = name
}

var B = function() {
  A.apply(this, arguments)
}

B.prototype.getName = function() {
  return this.name
}

var b = new B('sven')
console.log(b.getName())

2.借用数组的方法操作类数组(arguments)

借用push方法:

(function(){
  Array.prototype.push.call(arguments, 3) // 借助Array的方法向arguments中push一个3
  console.log(arguments) // 输出[1,2,3]
})(1,2)

借用shift方法

(function(){
  Array.prototype.shift.call(arguments) // 借助Array的方法向arguments中push一个3
  console.log(arguments) // 输出[2]
})(1,2)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值