理解js中apply與call

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ù)列表的集合

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 開(kāi)始看到j(luò)avascript的函數(shù)apply和call時(shí),非常的模糊,由于最近在找工作應(yīng)對(duì)面試,在網(wǎng)上看到一些文章...
    小搖歌閱讀 654評(píng)論 0 0
  • 一直都沒(méi)太明白apply()與call()的具體使用原理,今日閑來(lái)無(wú)事,決定好好研究一番。 JavaScript中...
    神秘者007閱讀 299評(píng)論 0 1
  • 第5章 引用類(lèi)型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類(lèi)型 使用基本類(lèi)型...
    大學(xué)一百閱讀 3,271評(píng)論 0 4
  • 1.背景介紹 call和apply都是為了改變某個(gè)函數(shù)運(yùn)行時(shí)的context即上下文而存在的,換句話(huà)說(shuō),就是為了改...
    遠(yuǎn)望的云閱讀 604評(píng)論 0 1
  • 在JavaScript中,call、apply和bind是Function對(duì)象自帶的三個(gè)方法,這三個(gè)方法的主要作用...
    人不中二枉少年閱讀 509評(píng)論 0 6