Javascript調(diào)用函數(shù)方法的幾種方式介紹
javascript語法靈活,同一個(gè)功能有五六種實(shí)現(xiàn)方式并不罕見,然后再加上有些反人類的原型繼承和異步特性,就更讓人一頭霧水了。我經(jīng)常搞不清楚call,apply之間的區(qū)別,今天就記錄一下,以免再忘了。
在javascript中,方法可以通過以下幾種方式執(zhí)行:
1.func(),這是最直接最常見的調(diào)用方式,也符合一般人的思維邏輯,但是在某些情況下有一些不足,下面會(huì)解釋。
2.(function(arg){})(window),匿名方法調(diào)用,在構(gòu)造命名空間時(shí)比較有用,后面的括號中的參數(shù)與匿名方法中的入?yún)⒁灰粚?yīng)。
3.func.bind(sth)(),mozilla手冊中提到bind是在ECMA-262 5th Edition中新增的一個(gè)特性,這里單獨(dú)列出來作為一種調(diào)用方式是因?yàn)樗鼜浹a(bǔ)了直接調(diào)用中不能綁定作用域的缺陷。
4.func.call(),這是第二種調(diào)用方式,每個(gè)方法的原型中都定義了call方法,用來執(zhí)行當(dāng)前方法。
5.func.apply(),call的雙胞胎兄弟。
func()
這是最常見的調(diào)用方式,在任何語言中隨處可見。func(x, y)可以傳入不同的參數(shù)。在某些語言,例如php,java中,這種調(diào)用足以解決一切問題。但是javascript是一門函數(shù)式語言,閉包的概念和一個(gè)奇怪的關(guān)鍵詞this決定了這種調(diào)用方式的不足。this應(yīng)該可以解釋為當(dāng)前代碼段的作用域,會(huì)隨著代碼執(zhí)行到不同的片段而改變,但是某些情況下我們不希望這個(gè)this被改變,例如綁定在某些dom上的事件,我們肯定不希望他們被調(diào)用的時(shí)候this被轉(zhuǎn)移到了window對象上,但有時(shí)候確實(shí)如此,再比如下面的代碼。
var a ={};
var func = function(x) {
console.log(this);
};
a.onclick = function() {
var x = 100;
func(x);
};
a.onclick();
可以把a(bǔ)想象成頁面中的一個(gè)鏈接,由于我們只是想將定義好的方法綁定到onclick事件上,而不是立刻調(diào)用它,而且這個(gè)方法擁有一個(gè)參數(shù),所以我們需要用一個(gè)匿名方法將他包起來傳遞給a的onclick事件。這樣就有了一個(gè)問題,func中的this變成了全局對象window,顯然我們并不希望如此。這個(gè)時(shí)候,使用func()這種直接調(diào)用的方式就不行了,于是我們需要將func外的this綁定到func方法上。于是就有了bind,call,apply方法。
bind
bind的目的非常簡單,返回一個(gè)綁定了this對象的相同方法。上面的代碼修改一行就可以實(shí)現(xiàn)綁定this在a對象上目的。
var a ={};
var func = function(x) {
console.log(this);
};
a.onclick = function() {
var x = 100;
func.bind(this)(x); // bind here
};
a.onclick();
這樣,onclick事件的this就不會(huì)像無頭蒼蠅一樣到處亂跑啦。
call & apply
call和apply要放在一起講,因?yàn)樗麄儗?shí)在太像了。他們都支持多參數(shù),而且第一個(gè)參數(shù)都是即將綁定的this對象,第二個(gè)參數(shù)則是他們的區(qū)別所在,call使用獨(dú)立的參數(shù)作為調(diào)用方法的入?yún)?,apply使用一個(gè)數(shù)組作為入?yún)ⅰS械臅r(shí)候我們并不是不想改變this對象,而是想人為的將他綁定到別的對象上,這個(gè)時(shí)候call和apply是很好用的。(并不是說不能用bind,不過貌似bind出現(xiàn)的比較晚,可能瀏覽器兼容性不好)。舉個(gè)栗子:
a = {
func: function() {
this.x += 1;
},
x: 0
};
b = {
a: a,
x: 20
};
for(var i = 0; i < 10; i++){
b.a.func();
}
console.log(a.x);
console.log(b.x);
上面的a和b對象中都有x,我們希望func能針對性的修改對應(yīng)的x,但是直接調(diào)用只可能修改func作用域中的x,也就是a.x。修改一下代碼,就可以實(shí)現(xiàn)修改b.x目的
a = {
func: function() {
this.x += 1;
},
x: 0
};
b = {
a: a,
x: 20
};
for(var i = 0; i < 10; i++){
b.a.func.call(b); // bind this to b
}
console.log(a.x);
console.log(b.x);
這個(gè)栗子舉得不好,有點(diǎn)牽強(qiáng)附會(huì),而且這是一種很容易讓人迷惑的代碼風(fēng)格,有適用的場景,但不是處處都可用。
- Android WebView的使用方法及與JS 相互調(diào)用
- Android編程使用WebView實(shí)現(xiàn)與Javascript交互的方法【相互調(diào)用參數(shù)、傳值】
- Objective-C 代碼與Javascript 代碼相互調(diào)用實(shí)例
- 淺談js中子頁面父頁面方法 變量相互調(diào)用
- 基于js里調(diào)用函數(shù)時(shí),函數(shù)名帶括號和不帶括號的區(qū)別
- JS中使用apply方法通過不同數(shù)量的參數(shù)調(diào)用函數(shù)的方法
- JavaScript中調(diào)用函數(shù)的4種方式代碼實(shí)例
- 一個(gè)Js文件函數(shù)中調(diào)用另一個(gè)Js文件函數(shù)的方法演示
相關(guān)文章
基于JavaScript實(shí)現(xiàn)自定義滾動(dòng)條
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)自定義滾動(dòng)條,可以直接使用的滾動(dòng)條,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01利用d3.js制作連線動(dòng)畫圖與編輯器的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于如何利用d3.js制作連線動(dòng)畫圖與編輯器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用d3.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09微信小程序中的video視頻實(shí)現(xiàn) 自定義播放按鈕、封面圖、視頻封面上文案
這篇文章主要介紹了微信小程序中的video視頻實(shí)現(xiàn) 自定義播放按鈕、封面圖、視頻封面上文案,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01javascript實(shí)現(xiàn)十秒鐘后注冊按鈕可點(diǎn)擊的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)十秒鐘后注冊按鈕可點(diǎn)擊的方法,涉及javascript時(shí)間及樣式操作的相關(guān)技巧,需要的朋友可以參考下2015-05-05微信小程序自定義tabbar custom-tab-bar 6s出不來解決方案(cover-view不兼容)
這篇文章主要介紹了微信小程序自定義tabbar custom-tab-bar 6s出不來解決方案,cover-view不兼容問題,需要的朋友可以參考下2019-11-11