js中call和apply的区别和用法

call和apply的区别

JavaScript中每一个Function对象都有一个call和apply方法,它们的语法分别为:
/*apply()方法*/
function.apply(thisObj, [, argArray])

/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [, ...argN]]]]);

它们各自的定义:
apply: 调用一个对象的方法,用另一个对象替换当前对象。例如:B.apply(A, arguments); 即A对象应用B对象的方法。
call: 调用一个对象的方法,用另一个对象替换当前对象。例如:B.call(A, args1, args2);即A对象调用B对象的方法。

它们的共同之处:
都可以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象

不同之处在于:
apply: 最多只能有两个参数–新this对象和一个数组argArray。如果给该方法传递多个参数,则把这些参数都写到数组里面,当然,即使只有一个参数,也要写到数组里面。如果argArray不是一个有效的数组或者arguments对象,那么将导致类型错误,TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法被传递任何参数。

call: 它可以接受多个参数,第一个参数于apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法互相调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变指针。如果没有提供thisObj参数,那么Global对象被用作thisObj。

实际上,apply和call的功能是一样的,只是传入的参数列表的形式不同。

示例代码:
(1)基本用法:

function calcSalary(base, performace,bonus){ //该函数是一个计算工资的函数,三个参数分别为基本工资,绩效,奖金
   console.log(this.name, base + performace + bonus);
}
var a = {
  name: lilei
};
var b = {
  name: hanmeimei
};
calcSalay.call(a, 10000,1000,2000); //call依次列出参数
calcSalay.apply(b, [10000, 2000, 3000]); //使用apply时,当至少有两个参数的时候,从第二个参数开始,都要放在数组中,而上面的call只需要依次列出来即可

(2)实现继承
function Animal(name){
   this.name = name;
   this.showName = function(){
     console.log(this.name);
   }
}
function Dog(name){
   Animal.apply(this, [name]);
}
var dog = new Dog('二哈');
dog.showName();

(3)多重继承

function ClassA(){
   this.numAdd = function(a, b){
    console.log(a + b);
  }
}
function ClassB(){
   this.numSub = function(a, b){
     console.log(a - b);
  }
}
function ClassC(){
   ClassA.apply(this);
   ClassB.apply(this);
}
var c = new ClassC();
c.numAdd(1, 2); //3
c.numSub(4, 2); //2

apply的一些妙用

(1) Math.max可以实现得到数组中最大的一项:
因为Math.max不支持Math.max([param1, param2])也就是数组,但是它支持Math.max(param1, param2…),所以可以根据apply的特点来解决 var max = Math.max.apply(null, array),这样就可以轻易地得到数组中的一个最大值(apply会将一个数组转换为一个参数接一个参数的方式传递给方法)。
在这里调用的时候第一个参数给了null,这是因为没有对象去调用这个方法,我们只需要用这个方法帮我们运算,得到返回的结果即可,所以直接传递了一个null过去。
同理用这种方法也可以得到一个数组中的最小值:Math.min.apply(null, array);

(2) Array.prototype.push 可以实现两个数组的合并
同样push方法没有提供push一个数组,但是它提供了push(param1, param2,…paramN),同样也可以用apply来转换一下数组,即:
var arr1 = new Array("1", "2", "3");
var arr2 =- new Array("3","4","5");
Array.prototype.push.apply(arr1, arr2); //返回合并之后的数组的长度
如果想要合并之后的数组,看arr1即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值