1. apply和call的定义
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args-->arguments)
/*定义一个人类*/
function Person(name,age) {
this.name=name;
this.age=age;
}
/*定义一个学生类*/
function Student(name,age,grade) {
Person.apply(this,arguments);
this.grade=grade;
}
//创建一个学生类
var student=new Student("qian",21,"一年级");
console.log("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
//返回结果:name:qian age:21 grade:一年级
分析:
Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“qian”,”21”,”一年级”];
也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在
this.name等之类的语句,这样就将属性创建到了student对象里面
call:和apply方法类似,只是参数不一样
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
/*定义一个人类*/
function Person(name,age) {
this.name=name; this.age=age;
}
/*定义一个学生类*/
functionStudent(name,age,grade) {
Person.apply(this,name,age);
this.grade=grade;
}
//创建一个学生类
var student=new Student("qian",21,"一年级");
console.log("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);
//返回结果:name:qian age:21 grade:一年级
2. 什么情况下用apply,什么情况下用call
apply :在给对象参数的情况下,如果参数的形式是数组的时候,比如apply示例里面传递了参数
arguments
,这个参数是数组类型,并且在调用Person
的时候参数的列表是对应一致的(也就是Person
和Student
的参数列表前两位是一致的) 就可以采用call:如果我的
Person
的参数列表是这样的(age,name)
,而Student的参数列表是(name,age,grade)
,这样就可以用call来实现了,也就是直接指定参数列表对应值的位置Person.call(this,age,name,grade)
;
3. apply的其他巧妙用法(一般在什么情况下可以使用apply)
可以将一个数组默认的转换为一个参数列表,如[param1,param2,param3]
转换为param1,param2,param3
,借助apply的这点特性,所以就有了以下高效率的方法:
-
Math.max
得到数组中最大的一项
因为Math.max
参数里面不支持Math.max([param1,param2])
也就是数组,但是它支持Math.max(param1,param2,param3…)
,所以可以根据刚才apply
的那个特点来解决,apply
会将一个数组装换为一个参数接一个参数的传递给方法
var array=[1,2,12,342,123];
var max=Math.max.apply(null,array);
console.log(max);//342
这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去
-
Array.prototype.push
可以实现两个数组合并
push
方法不能直接添加一个数组,但是它提供了push(param1,param,…paramN)
所以同样也可以通过apply
来装换一下这个数组
var arr1=new Array("1","2","3");
var arr2=new Array("4","5","6");
Array.prototype.push.apply(arr1,arr2);
console.log(arr1);//["1", "2", "3", "4", "5", "6"]