JavaScript中apply與call的用法意義及區(qū)別說(shuō)明
更新時(shí)間:2010年04月01日 14:15:49 作者:
JavaScript中有一個(gè)call和apply方法,其作用基本相同,但也有略微的區(qū)別。
apply和call,它們的作用都是將函數(shù)綁定到另外一個(gè)對(duì)象上去運(yùn)行,兩者僅在定義參數(shù)的方式有所區(qū)別:
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
從函數(shù)原型可以看到,第一個(gè)參數(shù)都被取名為thisArg,即所有函數(shù)內(nèi)部的this指針都會(huì)被賦值為thisArg,這就實(shí)現(xiàn)了將函數(shù)作為另外一個(gè)對(duì)象的方法運(yùn)行的目的。兩個(gè)方法除了thisArg參數(shù),都是為Function對(duì)象傳遞的參數(shù)。下面的代碼說(shuō)明了apply和call方法的工作方式:
//定義一個(gè)函數(shù)func1,具有屬性p和方法A
function func1(){
this.p="func1-";
this.A=function(arg){
alert(this.p+arg);
}
}
//定義一個(gè)函數(shù)func2,具有屬性p和方法B
function func2(){
this.p="func2-";
this.B=function(arg){
alert(this.p+arg);
}
}
var obj1=new func1();
var obj2=new func2();
obj1.A("byA"); //顯示func1-byA
obj2.B("byB"); //顯示func2-byB
obj1.A.apply(obj2,["byA"]); //顯示func2-byA,其中[“byA”]是僅有一個(gè)元素的數(shù)組,下同
obj2.B.apply(obj1,["byB"]); //顯示func1-byB
obj1.A.call(obj2,"byA"); //顯示func2-byA
obj2.B.call(obj1,"byB"); //顯示func1-byB
可以看出,obj1的方法A被綁定到obj2運(yùn)行后,整個(gè)函數(shù)A的運(yùn)行環(huán)境就轉(zhuǎn)移到了obj2,即this指針指向了obj2。同樣obj2的函數(shù)B也可以綁定到obj1對(duì)象去運(yùn)行。代碼的最后4行顯示了apply和call函數(shù)參數(shù)形式的區(qū)別。
與arguments的length屬性不同,函數(shù)對(duì)象還有一個(gè)屬性length,它表示函數(shù)定義時(shí)所指定參數(shù)的個(gè)數(shù),而非調(diào)用時(shí)實(shí)際傳遞的參數(shù)個(gè)數(shù)。例如下面的代碼將顯示2:
function sum(a,b){ return a+b;}
下面來(lái)看看JS手冊(cè)中對(duì)call的解釋?zhuān)?
call 方法
調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
參數(shù)
thisObj
可選項(xiàng)。將被用作當(dāng)前對(duì)象的對(duì)象。
arg1, arg2, , argN
可選項(xiàng)。將被傳遞方法參數(shù)序列。
說(shuō)明
call 方法可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法。call 方法可將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對(duì)象。
如果沒(méi)有提供 thisObj 參數(shù),那么 Global 對(duì)象被用作 thisObj。
說(shuō)明白一點(diǎn)其實(shí)就是更改對(duì)象的內(nèi)部指針,即改變對(duì)象的this指向的內(nèi)容。這在面向?qū)ο蟮膉s編程過(guò)程中有時(shí)是很有用的。
引用網(wǎng)上一個(gè)代碼段,運(yùn)行后自然就明白其道理。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
call函數(shù)和apply方法的第一個(gè)參數(shù)都是要傳入給當(dāng)前對(duì)象的對(duì)象,及函數(shù)內(nèi)部的this。后面的參數(shù)都是傳遞給當(dāng)前對(duì)象的參數(shù)。
運(yùn)行如下代碼:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
可見(jiàn)分別彈出了func和var。到這里就對(duì)call的每個(gè)參數(shù)的意義有所了解了。
對(duì)于apply和call兩者在作用上是相同的,但兩者在參數(shù)上有區(qū)別的。
對(duì)于第一個(gè)參數(shù)意義都一樣,但對(duì)第二個(gè)參數(shù):
apply傳入的是一個(gè)參數(shù)數(shù)組,也就是將多個(gè)參數(shù)組合成為一個(gè)數(shù)組傳入,而call則作為call的參數(shù)傳入(從第二個(gè)參數(shù)開(kāi)始)。
如 func.call(func1,var1,var2,var3)對(duì)應(yīng)的apply寫(xiě)法為:func.apply(func1,[var1,var2,var3])
同時(shí)使用apply的好處是可以直接將當(dāng)前函數(shù)的arguments對(duì)象作為apply的第二個(gè)參數(shù)傳入
javascript apply用法 補(bǔ)充
funObj.apply([thisObj[,argArray]])
應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
functionObj的方法執(zhí)行時(shí),函數(shù)中的this對(duì)象會(huì)被thisObj替換掉。
thisObj 可選項(xiàng)。將被用作當(dāng)前對(duì)象的對(duì)象。
argArray 可選項(xiàng)。將被傳遞給該函數(shù)的參數(shù)數(shù)組。
//apply在對(duì)象繼承方面的應(yīng)用,不使用prototype,隱式的將父對(duì)象屬性賦給了子對(duì)象
function par(name)
{
this.parname=name;
}
function child(chname,parname){
this.chname=chname;
par.apply(this,new Array(parname));
};
var o=new child("john","Mr john");
alert(o.parname+";"+o.chname);
//apply可以在通用的方法調(diào)用方面進(jìn)行使用
window.onunload=function()
{
alert("unload event is fired!");
}
function sayBye(name,toName)
{
alert(name+" says bye to "+toName);
}
function sayEndBiz(name,toName,content)
{
alert(name+" ends his talk about "+content +" with "+toName);
}
function addTo(args,func)
{
var oldHandler=window.onunload||function(){};
window.onunload=function()
{
func.apply(window,args);
oldHandler.apply(window, args);
}
}
addTo(new Array("John","everyone"),sayBye);
addTo(new Array("John","everyone","deveopment strategy of the company"),sayEndBiz)
Function.prototype.apply(thisArg,argArray);
Function.prototype.call(thisArg[,arg1[,arg2…]]);
從函數(shù)原型可以看到,第一個(gè)參數(shù)都被取名為thisArg,即所有函數(shù)內(nèi)部的this指針都會(huì)被賦值為thisArg,這就實(shí)現(xiàn)了將函數(shù)作為另外一個(gè)對(duì)象的方法運(yùn)行的目的。兩個(gè)方法除了thisArg參數(shù),都是為Function對(duì)象傳遞的參數(shù)。下面的代碼說(shuō)明了apply和call方法的工作方式:
復(fù)制代碼 代碼如下:
//定義一個(gè)函數(shù)func1,具有屬性p和方法A
function func1(){
this.p="func1-";
this.A=function(arg){
alert(this.p+arg);
}
}
//定義一個(gè)函數(shù)func2,具有屬性p和方法B
function func2(){
this.p="func2-";
this.B=function(arg){
alert(this.p+arg);
}
}
var obj1=new func1();
var obj2=new func2();
obj1.A("byA"); //顯示func1-byA
obj2.B("byB"); //顯示func2-byB
obj1.A.apply(obj2,["byA"]); //顯示func2-byA,其中[“byA”]是僅有一個(gè)元素的數(shù)組,下同
obj2.B.apply(obj1,["byB"]); //顯示func1-byB
obj1.A.call(obj2,"byA"); //顯示func2-byA
obj2.B.call(obj1,"byB"); //顯示func1-byB
可以看出,obj1的方法A被綁定到obj2運(yùn)行后,整個(gè)函數(shù)A的運(yùn)行環(huán)境就轉(zhuǎn)移到了obj2,即this指針指向了obj2。同樣obj2的函數(shù)B也可以綁定到obj1對(duì)象去運(yùn)行。代碼的最后4行顯示了apply和call函數(shù)參數(shù)形式的區(qū)別。
與arguments的length屬性不同,函數(shù)對(duì)象還有一個(gè)屬性length,它表示函數(shù)定義時(shí)所指定參數(shù)的個(gè)數(shù),而非調(diào)用時(shí)實(shí)際傳遞的參數(shù)個(gè)數(shù)。例如下面的代碼將顯示2:
復(fù)制代碼 代碼如下:
function sum(a,b){ return a+b;}
下面來(lái)看看JS手冊(cè)中對(duì)call的解釋?zhuān)?
call 方法
調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
參數(shù)
thisObj
可選項(xiàng)。將被用作當(dāng)前對(duì)象的對(duì)象。
arg1, arg2, , argN
可選項(xiàng)。將被傳遞方法參數(shù)序列。
說(shuō)明
call 方法可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法。call 方法可將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對(duì)象。
如果沒(méi)有提供 thisObj 參數(shù),那么 Global 對(duì)象被用作 thisObj。
說(shuō)明白一點(diǎn)其實(shí)就是更改對(duì)象的內(nèi)部指針,即改變對(duì)象的this指向的內(nèi)容。這在面向?qū)ο蟮膉s編程過(guò)程中有時(shí)是很有用的。
引用網(wǎng)上一個(gè)代碼段,運(yùn)行后自然就明白其道理。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
call函數(shù)和apply方法的第一個(gè)參數(shù)都是要傳入給當(dāng)前對(duì)象的對(duì)象,及函數(shù)內(nèi)部的this。后面的參數(shù)都是傳遞給當(dāng)前對(duì)象的參數(shù)。
運(yùn)行如下代碼:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
可見(jiàn)分別彈出了func和var。到這里就對(duì)call的每個(gè)參數(shù)的意義有所了解了。
對(duì)于apply和call兩者在作用上是相同的,但兩者在參數(shù)上有區(qū)別的。
對(duì)于第一個(gè)參數(shù)意義都一樣,但對(duì)第二個(gè)參數(shù):
apply傳入的是一個(gè)參數(shù)數(shù)組,也就是將多個(gè)參數(shù)組合成為一個(gè)數(shù)組傳入,而call則作為call的參數(shù)傳入(從第二個(gè)參數(shù)開(kāi)始)。
如 func.call(func1,var1,var2,var3)對(duì)應(yīng)的apply寫(xiě)法為:func.apply(func1,[var1,var2,var3])
同時(shí)使用apply的好處是可以直接將當(dāng)前函數(shù)的arguments對(duì)象作為apply的第二個(gè)參數(shù)傳入
javascript apply用法 補(bǔ)充
funObj.apply([thisObj[,argArray]])
應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。
functionObj的方法執(zhí)行時(shí),函數(shù)中的this對(duì)象會(huì)被thisObj替換掉。
thisObj 可選項(xiàng)。將被用作當(dāng)前對(duì)象的對(duì)象。
argArray 可選項(xiàng)。將被傳遞給該函數(shù)的參數(shù)數(shù)組。
復(fù)制代碼 代碼如下:
//apply在對(duì)象繼承方面的應(yīng)用,不使用prototype,隱式的將父對(duì)象屬性賦給了子對(duì)象
function par(name)
{
this.parname=name;
}
function child(chname,parname){
this.chname=chname;
par.apply(this,new Array(parname));
};
var o=new child("john","Mr john");
alert(o.parname+";"+o.chname);
//apply可以在通用的方法調(diào)用方面進(jìn)行使用
window.onunload=function()
{
alert("unload event is fired!");
}
function sayBye(name,toName)
{
alert(name+" says bye to "+toName);
}
function sayEndBiz(name,toName,content)
{
alert(name+" ends his talk about "+content +" with "+toName);
}
function addTo(args,func)
{
var oldHandler=window.onunload||function(){};
window.onunload=function()
{
func.apply(window,args);
oldHandler.apply(window, args);
}
}
addTo(new Array("John","everyone"),sayBye);
addTo(new Array("John","everyone","deveopment strategy of the company"),sayEndBiz)
您可能感興趣的文章:
- JavaScript中的apply()方法和call()方法使用介紹
- js中繼承的幾種用法總結(jié)(apply,call,prototype)
- javascript中apply和call方法的作用及區(qū)別說(shuō)明
- 詳解js中的apply與call的用法
- JS中改變this指向的方法(call和apply、bind)
- JavaScript中的apply和call函數(shù)詳解
- js中call與apply的用法小結(jié)
- js apply/call/caller/callee/bind使用方法與區(qū)別分析
- JS面向?qū)ο蟆rototype、call()、apply()
- JavaScript學(xué)習(xí)點(diǎn)滴 call、apply的區(qū)別
- 詳解JS中的this、apply、call、bind(經(jīng)典面試題)
- 淺談javascript中call()、apply()、bind()的用法
- js中apply()和call()的區(qū)別與用法實(shí)例分析
- 跟我學(xué)習(xí)javascript的call(),apply(),bind()與回調(diào)
- JavaScript中的this,call,apply使用及區(qū)別詳解
- javascript call和apply方法
- 深入理解JavaScript中的call、apply、bind方法的區(qū)別
- 再談JavaScript中bind、call、apply三個(gè)方法的區(qū)別與使用方式
相關(guān)文章
原生JS實(shí)現(xiàn)頂部導(dǎo)航欄顯示按鈕+搜索框功能
這篇文章主要介紹了原生js實(shí)現(xiàn)頂部導(dǎo)航欄顯示按鈕+搜索框功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
JavaScript中創(chuàng)建類(lèi)/對(duì)象的幾種方法總結(jié)
這篇文章主要是對(duì)JavaScript中創(chuàng)建類(lèi)/對(duì)象的幾種方法進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
a標(biāo)簽置灰不可點(diǎn)擊的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇a標(biāo)簽置灰不可點(diǎn)擊的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
一文教你如何實(shí)現(xiàn)localStorage的過(guò)期機(jī)制
要知道localStorage本身并沒(méi)有提供過(guò)期機(jī)制,既然如此那就只能我們自己來(lái)實(shí)現(xiàn)了,這篇文章主要給大家介紹了關(guān)于如何實(shí)現(xiàn)localStorage過(guò)期機(jī)制的相關(guān)資料,需要的朋友可以參考下2022-02-02
JS實(shí)現(xiàn)textarea通過(guò)換行或者回車(chē)把多行數(shù)字分割成數(shù)組并且去掉數(shù)組中空的值
這篇文章主要介紹了JS實(shí)現(xiàn)textarea通過(guò)換行或者回車(chē)把多行數(shù)字分割成數(shù)組并且去掉數(shù)組中空的值的相關(guān)資料,需要的朋友可以參考下2018-10-10
Web開(kāi)發(fā)中使用SVG圖標(biāo)的7種方法舉例總結(jié)
這篇文章主要介紹了7種嵌入SVG圖標(biāo)的方法,包括內(nèi)聯(lián)SVG、img標(biāo)簽、object標(biāo)簽、CSS背景圖像、SVG圖標(biāo)字體、use元素和JavaScript動(dòng)態(tài)加載,每種方法都有其優(yōu)勢(shì)和限制,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03
javascript實(shí)現(xiàn)信息的顯示和隱藏如注冊(cè)頁(yè)面
信息的顯示和隱藏在某些時(shí)候還是比較使用的,就比如注冊(cè)信息,下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以了解下2013-12-12

