作为一款面向对象语言,js中很多的方法都是被封装在构造函数中的,这些封装的方法只有特定的对象能够访问。而有些时候,我们希望能通过“借用”某个构造函数prototype中的方法,来实现某些取巧的功能。以下总结了一些call和apply的区别和使用方法。
一、区别
call和apply都是用来借用类方法使用的。而在使用时,区别就在于call和apply所需要的参数形势不同。
this.method.apply(newThis,[arguments]);
this.method.call(newThis,argument1[,argument2[,augument3...]]);
在使用时,会用newThis替换this,作为方法的作用对象。apply方法的参数是以一个数组的形式传入的,因此我们可以利用这一特征,对一些不支持数组参数的方法进行拓展(比如arr.push())。
二、使用范例
在构造算法时,我们经常会需要对传入的参数进行类型判断,进而达到保护函数的效果。而在判断参数类型时,typeof可以正确的识别六大基础数据类型(string,number,boolean,undefined,object null也是object;),在识别对象类型时,除了function的返回值是"function"以外,其他的对象类型都会返回"object"(这是因为其他的构造函数都是继承自Function原型)。为了正确识别所有的基础数据类型和内置对象类型,我们会使用Object.prototype.toString.call(obj)来判断。(注意此方法不能判断自定义对象类型。)
三、使用技巧
call和apply在一些不支持数组类型参数的方法上有着特别的作用。比如:
var arr1 = [1,2,3];
var arr2 = [4,5,6];
Array.prototype.push.apply(arr1,arr2);//会返回arr1的新长度,即6,arr1此时变为[1,2,3,4,5,6]
数组中push方法用来给数组1添加数据。而参数不支持数组。在使用apply方法时,会将参数arr2分解开来,化为一个一个的参数传入,这样就解决了难以连接两个数组的尴尬。注意合成arr2被添加在arr1的后面,而返回值是新的arr1中数据的个数。
同样,在Math.max判断一组参数中最大值的时候,也不支持数组类型参数。这个时候我们可以使用Math.max.apply(Math,[12,45,23])来传入一个数组。判断最小值同理。
四、总结以及其他用途
call和apply不仅可以借用系统的默认方法,也可以借用自定义构造函数中的方法甚至构造函数本身(这样的话将会调用构造函数,若传入的参数是(this,arguments),那么调用的构造函数中的对象也会被复制到this构造函数中)。
function Name(name){
this.name = name;
this.introduce = function(){
alert(this.name);
};
}//名称构造函数,包括一个姓名,一个弹出姓名的方法。
function People(name, age, classNo){
Name.apply(this,arguments);
this.age = age;
this.classNo = classNo;
}//创建一个人物构造函数,在创建时,调用Name构造函数
var Alex = new People("Alex", 21, "six");//创建一个People实例,而在实例被构造时
//会先调用Name.apply(this,arguments)语句,这里的this为Alex实例。则,构造函数Name中的name对象,introduce方法都会被创建在Alex实例中。
Alex.name;//"Alex"
Alex.introduce();//alert
Alex.age;//21
Alex.classNo;//"six"
在使用时应当注意使用的方式,灵活应用。