JavaScript中的每一個Function對象都有一個apply()方法和一個call()方法,它們的語法分別為:
/*apply()方法*/
function.apply(thisObj[, argArray])
/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
它們各自的定義:
apply:調(diào)用一個對象的一個方法镐确,用另一個對象替換當前對象瓜晤。例如:B.apply(A, arguments);即A對象應(yīng)用B對象的方法锥余。
call:調(diào)用一個對象的一個方法,用另一個對象替換當前對象痢掠。例如:B.call(A, args1,args2);即A對象調(diào)用B對象的方法驱犹。
它們的共同之處:
都“可以用來代替另一個對象調(diào)用一個方法,將一個函數(shù)的對象上下文從初始的上下文改變?yōu)橛蓆hisObj指定的新對象”足画。
它們的不同之處:
apply:最多只能有兩個參數(shù)——新this對象和一個數(shù)組argArray雄驹。如果給該方法傳遞多個參數(shù),則把參數(shù)都寫進這個數(shù)組里面锌云,當然荠医,即使只有一個參數(shù),也要寫進數(shù)組里桑涎。如果argArray不是一個有效的數(shù)組或arguments對象彬向,那么將導(dǎo)致一個TypeError。如果沒有提供argArray和thisObj任何一個參數(shù)攻冷,那么Global對象將被用作thisObj娃胆,并且無法被傳遞任何參數(shù)。
call:它可以接受多個參數(shù)等曼,第一個參數(shù)與apply一樣里烦,后面則是一串參數(shù)列表。這個方法主要用在js對象各方法相互調(diào)用的時候禁谦,使當前this實例指針保持一致胁黑,或者在特殊情況下需要改變this指針。如果沒有提供thisObj參數(shù)州泊,那么 Global 對象被用作thisObj丧蘸。
實際上,apply和call的功能是一樣的遥皂,只是傳入的參數(shù)列表形式不同力喷。
示例代碼:
(1)基本用法
function add(a,b){
return a+b;
}
function sub(a,b){
return a-b;
}
var a1 = add.apply(sub,[4,2]); //sub調(diào)用add的方法
var a2 = sub.apply(add,[4,2]);
alert(a1); //6
alert(a2); //2
/*call的用法*/
var a1 = add.call(sub,4,2);
(2)實現(xiàn)繼承
```javascript
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.apply(this,[name]);
}
var cat = new Cat("咕咕");
cat.showName();
/*call的用法*/
Animal.call(this,name);
(3)多重繼承
function Class10(){
this.showSub = function(a,b){
alert(a - b);
}
}
function Class11(){
this.showAdd = function(a,b){
alert(a + b);
}
}
function Class12(){
Class10.apply(this);
Class11.apply(this);
// Class10.call(this);
//Class11.call(this);
}
var c2 = new Class12();
c2.showSub(3,1); //2
c2.showAdd(3,1); //4
apply的一些其他巧妙用法
(1)Math.max 可以實現(xiàn)得到數(shù)組中最大的一項:
因為Math.max不支持Math.max([param1,param2])也就是數(shù)組刽漂,但是它支持Math.max(param1,param2...),所以可以根據(jù)apply的特點來解決 var max=Math.max.apply(null,array)弟孟,這樣就輕易的可以得到一個數(shù)組中的最大項(apply會將一個數(shù)組轉(zhuǎn)換為一個參數(shù)接一個參
數(shù)的方式傳遞給方法)
這塊在調(diào)用的時候第一個參數(shù)給了null贝咙,這是因為沒有對象去調(diào)用這個方法,我只需要用這個方法幫我運算拂募,得到返回的結(jié)果就行庭猩,所以直接傳遞了一個null過去。
用這種方法也可以實現(xiàn)得到數(shù)組中的最小項:Math.min.apply(null,array)
(2)Array.prototype.push可以實現(xiàn)兩個數(shù)組的合并
同樣push方法沒有提供push一個數(shù)組没讲,但是它提供了push(param1,param2...paramN)眯娱,同樣也可以用apply來轉(zhuǎn)換一下這個數(shù)組,即:
var arr1=new Array("1","2","3");
var arr2=new Array("4","5","6");
Array.prototype.push.apply(arr1,arr2); //得到合并后數(shù)組的長度爬凑,因為push就是返回一個數(shù)組的長度
也可以這樣理解徙缴,arr1調(diào)用了push方法,參數(shù)是通過apply將數(shù)組轉(zhuǎn)換為參數(shù)列表的集合
通常在什么情況下嘁信,可以使用apply類似Math.max等之類的特殊用法:
一般在目標函數(shù)只需要n個參數(shù)列表于样,而不接收一個數(shù)組的形式,可以通過apply的方式巧妙地解決這個問題潘靖。