call與apply的方法定義:
call方法:
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
定義:調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
說(shuō)明:
call 方法可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法。call 方法可將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?this指定的新對(duì)象。
==================================
apply方法:
function.apply(thisObj[, argArray])
定義:應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
apply:最多只能有兩個(gè)參數(shù)——新this對(duì)象和一個(gè)數(shù)組argArray。如果給該方法傳遞多個(gè)參數(shù),則把參數(shù)都寫(xiě)進(jìn)這個(gè)數(shù)組里面,當(dāng)然,即使只有一個(gè)參數(shù),也要寫(xiě)進(jìn)數(shù)組里。如果argArray不是一個(gè)有效的數(shù)組或arguments對(duì)象,那么將導(dǎo)致一個(gè)TypeError。如果沒(méi)有提供argArray和thisObj任何一個(gè)參數(shù),那么Global對(duì)象將被用作thisObj,并且無(wú)法被傳遞任何參數(shù)。
call:它可以接受多個(gè)參數(shù),第一個(gè)參數(shù)與apply一樣,后面則是一串參數(shù)列表。這個(gè)方法主要用在js對(duì)象各方法相互調(diào)用的時(shí)候,使當(dāng)前this實(shí)例指針保持一致,或者在特殊情況下需要改變this指針。如果沒(méi)有提供thisObj參數(shù),那么 Global 對(duì)象被用作thisObj。
實(shí)際上,apply和call的功能是一樣的,只是傳入的參數(shù)列表形式不同。
function jia(a,b)
{
alert(a+b);
}
function jian(a,b)
{
alert(a-b);
}
jia.call(jian,3,1);
看最后一句代碼jia.call(sub,3,1);
其實(shí)等同于 jia(3,1)
;結(jié)果為4;
還可以這樣寫(xiě)jia.call(this,3,1);
結(jié)果也是一樣的; 這個(gè)例子中的意思就是用 jia來(lái)替換 jian方法;
如過(guò)把它用apply寫(xiě)的話(huà)就是jia.apply(this,[3,1]);
或者jia.apply(jian,[3,1]);
;
這里要注意的是,js 中的函數(shù)其實(shí)是對(duì)象,函數(shù)名是對(duì) Function 對(duì)象的引用。
function Animal(){
this.name = "dog";
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var animal = new Animal(); //new新的實(shí)例
var cat = new Cat();
animal.showName.call(cat,",");
animal.showName.apply(cat,[]);
這段代碼的意思其實(shí)就是,把 animal 的方法放到cat上執(zhí)行,原來(lái)是沒(méi)有showName的方法的,現(xiàn)在可以用了!輸出的結(jié)果為‘Cat’;
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Cat");
cat.showName();
Animal.call(this) 的意思就是使用 Animal對(duì)象代替this對(duì)象,Cat對(duì)象就能夠直接調(diào)用Animal的方法以及屬性了,這里實(shí)現(xiàn)的是方法的繼承;cat繼承Animal里面的name;
function Class10()
{
this.showSub = function(a,b)
{
alert(a-b);
}
}
function Class11()
{
this.showAdd = function(a,b)
{
alert(a+b);
}
}
function Class2()
{
Class10.call(this);
Class11.call(this);
}
很簡(jiǎn)單,使用兩個(gè) call 就實(shí)現(xiàn)多重繼承了,當(dāng)然,js的繼承還有其他方法,例如使用原型鏈,只是在此說(shuō)明call 的用法。說(shuō)了call ,當(dāng)然還有 apply,這兩個(gè)方法基本上是一個(gè)意思,區(qū)別在于 call 的第二個(gè)參數(shù)可以是任意類(lèi)型,而apply的第二個(gè)參數(shù)必須是數(shù)組,也可以是arguments;
apply的一些其他巧妙用法(借鑒)
(1)Math.max 可以實(shí)現(xiàn)得到數(shù)組中最大的一項(xiàng):
因?yàn)镸ath.max不支持Math.max([param1,param2])也就是數(shù)組,但是它支持Math.max(param1,param2...),所以可以根據(jù)apply的特點(diǎn)來(lái)解決 var max=Math.max.apply(null,array),這樣就輕易的可以得到一個(gè)數(shù)組中的最大項(xiàng)(apply會(huì)將一個(gè)數(shù)組轉(zhuǎn)換為一個(gè)參數(shù)接一個(gè)參數(shù)的方式傳遞給方法)
這塊在調(diào)用的時(shí)候第一個(gè)參數(shù)給了null,這是因?yàn)闆](méi)有對(duì)象去調(diào)用這個(gè)方法,我只需要用這個(gè)方法幫我運(yùn)算,得到返回的結(jié)果就行,所以直接傳遞了一個(gè)null過(guò)去。
用這種方法也可以實(shí)現(xiàn)得到數(shù)組中的最小項(xiàng):Math.min.apply(null,array)
(2)Array.prototype.push可以實(shí)現(xiàn)兩個(gè)數(shù)組的合并
同樣push方法沒(méi)有提供push一個(gè)數(shù)組,但是它提供了push(param1,param2...paramN),同樣也可以用apply來(lái)轉(zhuǎn)換一下這個(gè)數(shù)組,即:
1.var arr1=new Array("1","2","3");
2.var arr2=new Array("4","5","6");
3.Array.prototype.push.apply(arr1,arr2); //得到合并后數(shù)組的長(zhǎng)度,因?yàn)閜ush就是返回一個(gè)數(shù)組的長(zhǎng)度也可以這樣理解,arr1調(diào)用了push方法,參數(shù)是通過(guò)apply將數(shù)組轉(zhuǎn)換為參數(shù)列表的集合