JS中使用apply、bind實(shí)現(xiàn)為函數(shù)或者類傳入動(dòng)態(tài)個(gè)數(shù)的參數(shù)
為紀(jì)念10年沒寫blog,第一篇博文就以這樣一個(gè)有趣的竅門開始吧 -___-
在ES5中,當(dāng)我們調(diào)用一個(gè)函數(shù)時(shí),如果要傳入的參數(shù)是根據(jù)其他函數(shù)或條件判斷生成的,也就是說不確定會(huì)傳入多少個(gè)參數(shù)時(shí),在不改變?cè)瘮?shù)的情況下該如何辦呢?
(當(dāng)然了,能避免此文所述情況發(fā)生就盡量避免,比如將參數(shù)改為object或array等等)

大部分人可能知道用apply能完美解決這個(gè)問題:

apply與call一樣會(huì)將第一個(gè)參數(shù)作為函數(shù)的調(diào)用對(duì)象,即改寫了調(diào)用函數(shù)內(nèi)的this指針為第一個(gè)參數(shù),如果不是對(duì)象的方法,可以不考慮this,傳入一個(gè)null即可。
而不同之處在于后面的參數(shù),apply將所有要傳入調(diào)用函數(shù)的參數(shù)放在一個(gè)數(shù)組中,call是與原函數(shù)一樣依次追加進(jìn)去。

既然是數(shù)組那就可控了,根據(jù)其他函數(shù)或邏輯判斷來生成數(shù)組,可達(dá)到傳入動(dòng)態(tài)個(gè)數(shù)參數(shù)的目的。
但是我遇到一個(gè)頭疼的問題,要在用new創(chuàng)建對(duì)象時(shí)傳入動(dòng)態(tài)個(gè)參數(shù),幾年才遇到一次的問題:

如果是用ES6,有了rest參數(shù),上述問題全都不是問題。注意,數(shù)組args前面加三個(gè)點(diǎn)并不是語(yǔ)法錯(cuò)誤,而是ES6提供的rest參數(shù)寫法,你可以理解為將...args替換為args數(shù)組去掉方括號(hào)后的字符。

但ES5里真的就沒有辦法實(shí)現(xiàn)了嗎?畢竟ES6大部分都是語(yǔ)法糖,可以用babel一類的工具編譯為ES5,帶著疑問,我們就用babel編譯一下看看得到什么:

看到最后一行驚呆了,別害怕,讓我們分析一下這句代碼。首先肢解一下,分三步來看:

1. 毫無疑問,用concat將null與我們的參數(shù)連接為一個(gè)數(shù)組,作為apply第二個(gè)參數(shù),即得到[null, 1, 2, 3];
2. 讓我們運(yùn)算一下apply,第一個(gè)參數(shù)Foo會(huì)取代Function來調(diào)用原生的bind方法,第二個(gè)參數(shù)數(shù)組的內(nèi)容將作為bind的參數(shù)傳入,即得到Foo.bind(null, 1, 2, 3);
3. bind方法第一個(gè)參數(shù)與apply、call類似,修改this指針,而后面的參數(shù)可以為函數(shù)植入默認(rèn)的前置參數(shù)值(preset leading argument),也就是說當(dāng)bind執(zhí)行完后在第一組小括號(hào)內(nèi)我們得到一個(gè)已經(jīng)注入了三個(gè)參數(shù)值的Foo類,暫且叫FooWithArgs;
最終,當(dāng)我們 new FooWithArgs(); 時(shí),就不用傳入任何參數(shù)了。等同于 new Foo(1, 2, 3);
- AngularJS報(bào)錯(cuò)$apply already in progress的解決方法分析
- AngularJS中$apply方法和$watch方法用法總結(jié)
- 詳解js中的apply與call的用法
- JS中使用apply方法通過不同數(shù)量的參數(shù)調(diào)用函數(shù)的方法
- 有關(guān)JavaScript中call()和apply() 的一些理解
- AngularJS中的$watch(),$digest()和$apply()區(qū)分
- JS中改變this指向的方法(call和apply、bind)
- js中apply和Math.max()函數(shù)的問題及區(qū)別介紹
相關(guān)文章
微信jssdk踩坑之簽名錯(cuò)誤invalid signature
這篇文章主要介紹了微信jssdk踩坑之簽名錯(cuò)誤invalid signature,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
layer.js之回調(diào)銷毀對(duì)話框的例子
今天小編就為大家分享一篇layer.js之回調(diào)銷毀對(duì)話框的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09
8個(gè)JavaScript條件語(yǔ)句優(yōu)化小技巧分享
在日常的開發(fā)中,我們經(jīng)常會(huì)編寫一些條件語(yǔ)句,過多的?if...else會(huì)導(dǎo)致代碼難以理解和維護(hù),今天小編來分享幾個(gè)優(yōu)化條件語(yǔ)句的小技巧,希望對(duì)大家有所幫助2022-07-07
前端微信H5公眾號(hào)實(shí)現(xiàn)授權(quán)登錄的方法總結(jié)
這篇文章主要介紹了如何在微信公眾號(hào)中實(shí)現(xiàn)網(wǎng)頁(yè)授權(quán)功能,包括創(chuàng)建微信服務(wù)公眾號(hào)、配置重定向地址、調(diào)試和開發(fā)使用等步驟,文中通過圖文及代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01
JS實(shí)現(xiàn)獲取進(jìn)今年第幾天是周幾的方法分析
這篇文章主要介紹了JS實(shí)現(xiàn)獲取進(jìn)今年第幾天是周幾的方法,結(jié)合實(shí)例形式對(duì)比分析了JavaScript進(jìn)行日期與天數(shù)運(yùn)算相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-06-06
EditPlus中的正則表達(dá)式 實(shí)戰(zhàn)(4)
這篇文章主要介紹了 EditPlus中的正則表達(dá)式 實(shí)戰(zhàn)(4)的相關(guān)資料,需要的朋友可以參考下2016-12-12
微信小程序間使用navigator跳轉(zhuǎn)傳值問題實(shí)例分析
這篇文章主要介紹了微信小程序間使用navigator跳轉(zhuǎn)傳值問題,結(jié)合實(shí)例形式分析了微信小程序間使用navigator跳轉(zhuǎn)傳值過程中遇到的問題與解決方法,需要的朋友可以參考下2020-03-03

