版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第JS手寫bind之處理new的情況詳解目錄new判斷函數(shù)是否通過new被調(diào)用new和bind實(shí)現(xiàn)完整的bind結(jié)尾大家好,我是前端西瓜哥。
之前寫了一篇關(guān)于JS中bind方法的實(shí)現(xiàn)的文章,并給出了實(shí)現(xiàn):
Ftotype.myBind=function(thisArg,...prefixArgs){
constfn=this;
returnfunction(...args){
returnfn.call(thisArg,...prefixArgs,...args);
但沒有處理通過new創(chuàng)建實(shí)例的情況。
因為很少會遇到給bind返回的函數(shù)做new操作的場景,所以我沒去考慮這種特殊情況。
但面試中還是會涉及到的,我們還是實(shí)現(xiàn)一下兼容new操作的bind寫法,順便學(xué)習(xí)一下new操作符。
因為存在一定上下文,在閱讀本文前,建議先閱讀前一篇文章:《前端面試題:手寫bind》。
new
我們先學(xué)習(xí)一下new操作符。
new用于通過函數(shù)來創(chuàng)建一個對象實(shí)例,在很多語言中都能看到。
JS的函數(shù),除了可以是普通函數(shù),比如:
functionsum(a,b){
returna+b;
還可以是構(gòu)造函數(shù),只需要在構(gòu)造時在它前面加一個new:
functionPerson(name,age){
=name;
this.age=age;
constperson=newPerson('前端西瓜哥',100)
//Person{name:'前端西瓜哥',age:100}
new創(chuàng)建一個新對象,做了下面幾件事:
創(chuàng)建一個空對象{};空對象的原型屬性__proto__指向構(gòu)造函數(shù)的原型對象Ptotype;函數(shù)中的this設(shè)置為這個空對象;如果該函數(shù)不返回一個對象,就返回這個this,否則返回這個對象。
判斷函數(shù)是否通過new被調(diào)用
怎么判斷一個函數(shù)正在被new操作符調(diào)用?
答案是使用instanceof判斷this是否為當(dāng)前函數(shù)的實(shí)例,即thisinstanceofFn為true,表示在通過new構(gòu)建實(shí)例。
我們看一個例子:
functionPerson(){
if(thisinstanceofPerson){
console.log('通過new構(gòu)建實(shí)例');
}else{
console.log('普通調(diào)用')
Person()//輸出:普通調(diào)用
newPerson()//輸出:通過new構(gòu)建實(shí)例
在Vuejs的源碼,你會看到下面代碼,這里也用到了這個技巧。
functionVue(options){
if(__DEV__!(thisinstanceofVue)){
warn('Vueisaconstructorandshouldbecalledwiththe`new`keyword')
this._init(options)
你在開發(fā)環(huán)境如果不通過new來使用Vue對象,會在控制臺提示你要通過new來調(diào)用Vue。
new和bind
如果我們new的是Ftotype.bind返回的新函數(shù),會發(fā)生什么事情?
functionPerson(name,age){
=name;
this.age=age;
constBoundPerson=Person.bind(null,'前端西瓜哥');
constboundPerson=newBoundPerson(100);
//Person{name:'前端西瓜哥',age:100}
boundPerson.__proto__===Ptotype
//true
結(jié)果等價于直接去new原始函數(shù)。
不同的是,仍舊可以進(jìn)行參數(shù)的預(yù)置。可以看到,構(gòu)造函數(shù)的第一個參數(shù),在調(diào)用bind的時候就提前設(shè)置為前端西瓜哥。
實(shí)現(xiàn)完整的bind
完整實(shí)現(xiàn)如下:
Ftotype.myBind=function(thisArg,...prefixArgs){
constfn=this;
constboundFn=function(...args){
//通過new使用當(dāng)前函數(shù)
if(thisinstanceofboundFn){
returnnewfn(...prefixArgs,...args);
//普通的方法調(diào)用當(dāng)前函數(shù)
returnfn.call(thisArg,...prefixArgs,...args);
boundFtotype=totype;
returnboundFn;
這里我通過thisinstanceofboundFn來判斷是否用了new,如果是,就直接new原始函數(shù)然后返回,記得帶上bind預(yù)置好的參數(shù)。
其他保持原樣(具體見上文《前端面試題:手寫bind》)。
boundFtotype=totype;這個可寫可不寫,只是讓bind返回的新函數(shù)的prototype指向原函數(shù)的prototype。
如果是原生bind返回的函數(shù),它是沒有protoype屬性的,可以認(rèn)為它是一種特別的函數(shù),而我們實(shí)現(xiàn)的bind返回的卻是一個普通函數(shù),所以并不能完全模擬的。
如果你追求完美的實(shí)現(xiàn),可以研讀一下Ftotype.bind的標(biāo)準(zhǔn):
然后再看看知名的core.js庫中對bind的實(shí)現(xiàn):
其中核心實(shí)現(xiàn)為:
//`Ftotype.bind`methodimplementation
//https://tc39.es/ecma262/#totype.bind
module.exports=Function.bind||functionbind(that/*,...args*/){
varF=aCallable(this);
varPrototype=F.prototype;
varpartArgs=arraySlice(arguments,1);
varboundFunction=functionbound(/*args...*/){
varargs=concat(partArgs,arraySlice(arguments));
returnthisinstanceofboundFunctionconstruct(F,args.length,args):F.apply(that,args);
if(isObject(Prototype))boundFtotype=Prototype;
returnboundFunction;
這里有更多的細(xì)節(jié):
這里判斷了this是否為函數(shù)類型,不是函數(shù)會報錯;F.prototype需要是一個對象或函數(shù),才能賦值給新函數(shù);使用了普通函數(shù)和arguments,這是為了兼容ES5
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 充填回收工安全規(guī)程競賽考核試卷含答案
- 硅油及乳液生產(chǎn)工安全應(yīng)急強(qiáng)化考核試卷含答案
- 油脂及脂肪酸加氫操作工安全理論評優(yōu)考核試卷含答案
- 玻璃制品機(jī)械成型工班組考核強(qiáng)化考核試卷含答案
- 中藥灸熨劑工崗前安全知識競賽考核試卷含答案
- 薄膜電阻器制造工崗前技術(shù)規(guī)范考核試卷含答案
- 九年級開學(xué)第一課主題班會課件
- 安全文明施工保證措施
- 交通應(yīng)急預(yù)案制定與演練制度
- 吊車保險培訓(xùn)課件大全
- 化工工藝安全管理與操作手冊
- 規(guī)范外匯交易管理制度
- 2026年美麗中國全國國家版圖知識競賽考試題庫(含答案)
- 高考英語讀后續(xù)寫技巧總結(jié)
- 2025年下半年河南鄭州市住房保障和房地產(chǎn)管理局招聘22名派遣制工作人員重點(diǎn)基礎(chǔ)提升(共500題)附帶答案詳解
- 維修事故協(xié)議書
- 2025ESC+EAS血脂管理指南要點(diǎn)解讀課件
- 2025至2030外周靜脈血栓切除裝置行業(yè)調(diào)研及市場前景預(yù)測評估報告
- 矛盾糾紛排查化解課件
- 2026年人力資源共享服務(wù)中心建設(shè)方案
- JJG(交通) 141-2017 瀝青路面無核密度儀
評論
0/150
提交評論