apply()和call()的区别

call和apply的区别

首先两者的作用是一样的,都是为了动态改变This,从语法我们可以看出它们所接受的参数不同:

1
2
obj.apply(thisObj, [arg1, arg2, ...]);
obj.call(thisObj, arg1, arg2, ...);

第一个参数都一样,即把this绑定到thisObj,这时候thisObj继承了this的属性和方法,重点在第二个参数,apply所接受的是一个数组参数,call所接受的是连续参数。

apply示例

我们来看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 定义一个人类
function Person(name,age)
{
this.name=name;
this.age=age;
}
//定义某个人类
function someOne(name,age,job){

Person.apply(this,arguments);
this.job=job;

}
var person1 = new someOne("Jack","21","doctor");
alert("My name is "+person1.name+". I am "+person1.age+" years old.And now I am a "+person1.job);
//弹出结果是My name is Jack. I am 21 years old.And now I am a doctor

可以看到我们在someOne类中并没有给name和age属性赋值,而是通过apply方法去继承Person类的方法,这个时候
apply(this,arguments)里的this指向创建的对象person1,arguments指向[“Jack”,”21”,”doctor”]。

call示例

第二个参数开始传入要劫持的属性

1
Person.call(this,name,age);

什么时候用apply,什么时候用call?

在给定参数列表,并且参数是数组类型,同时父子函数的参数列表顺序是一致的,即可用apply。如不一致,就得用call来实现了,参数列表顺序以父函数为准。举个例子,父函数Person(name,age),子函数someOne(age,name,job),这时候就得这样使用:Person.call(this,name,age)

实用的apply

利用apply可以把数组参数转为一个一个的参数传递给方法这个特性,我们可以为Math方法做一个良好的拓展。原生的Math.max()是不接受数组参数的,确实是个遗憾,不过现在我们可以这样写:Math.max.apply(null,array)去求最大值,同样也可以用Math.min.apply(null,array)求出数组里的最小值。